[IMP] project & its related module with removing of mx.datetime dependancy

bzr revid: mra@mra-laptop-20100812073145-h57aft3vbcxsmvu7
This commit is contained in:
PAP(OpenERP)
2010-08-12 13:01:45 +05:30
committed by Mustufa Rangwala
parent 279d41f156
commit c75affcd1c
21 changed files with 89 additions and 151 deletions
@@ -13,14 +13,6 @@
<act_window domain="[('user_id','=',uid),('state','&lt;&gt;','close')]" id="act_my_account" name="My accounts to invoice" res_model="account.analytic.account" view_id="view_account_analytic_simplified" view_mode="tree,form" view_type="form"/>
<!-- <record id="action_project_pipeline_user" model="ir.actions.act_window">-->
<!-- <field name="name">Pipeline of tasks</field>-->
<!-- <field name="res_model">report.task.user.pipeline.open</field>-->
<!-- <field name="view_type">form</field>-->
<!-- <field name="view_mode">graph,tree</field>-->
<!-- <field name="domain">[('user_id','in',department_users_get())]</field>-->
<!-- </record>-->
<record id="board_project_manager_form" model="ir.ui.view">
<field name="name">board.project.manager.form</field>
<field name="model">board.board</field>
+10 -2
View File
@@ -21,7 +21,7 @@
from lxml import etree
import time
from datetime import date, datetime
from datetime import datetime, date
from tools.translate import _
from osv import fields, osv
@@ -257,11 +257,19 @@ class project(osv.osv):
task_obj = self.pool.get('project.task')
result = []
for proj in self.browse(cr, uid, ids, context=context):
parent_id = context.get('parent_id', False) # check me where to pass context for parent id ??
parent_id = context.get('parent_id', False)
context.update({'analytic_project_copy': True})
new_date_start = time.strftime('%Y-%m-%d')
new_date_end = False
if proj.date_start and proj.date:
start_date = date(*time.strptime(proj.date_start,'%Y-%m-%d')[:3])
end_date = date(*time.strptime(proj.date,'%Y-%m-%d')[:3])
new_date_end = (datetime(*time.strptime(new_date_start,'%Y-%m-%d')[:3])+(end_date-start_date)).strftime('%Y-%m-%d')
new_id = project_obj.copy(cr, uid, proj.id, default = {
'name': proj.name +_(' (copy)'),
'state':'open',
'date_start':new_date_start,
'date':new_date_end,
'parent_id':parent_id}, context=context)
result.append(new_id)
cr.execute('select id from project_task where project_id=%s', (proj.id,))
+3 -3
View File
@@ -15,9 +15,9 @@
<field name="object">project.task</field>
</record>
<!--
Resource: project.project
-->
<!--
Resource: project.project
-->
<record id="all_projects_account" model="account.analytic.account">
<field name="name">Projects</field>
<field name="code">3</field>
+3 -62
View File
@@ -19,16 +19,11 @@
#
##############################################################################
from mx import DateTime
from mx.DateTime import now
import time
import tools
import netsvc
import sys
from osv import fields, osv
import ir
from tools.translate import _
import sys
import tools
from tools.translate import _
try:
@@ -61,59 +56,6 @@ class project_gtd_timebox(osv.osv):
'icon': fields.selection(tools.icons, 'Icon', size=64),
}
# def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
# res = super(project_gtd_timebox,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
# if (res['type']=='form') and ('record_id' in context):
# if context['record_id']:
# rec = self.browse(cr, uid, int(context['record_id']), context)
# else:
# iids = self.search(cr,uid, [('user_id','=',uid),('parent_id','=',False)], context=context)
# if len(iids):
# rec = self.browse(cr, uid, int(iids[0]), context=context)
# else:
# return res
# res['arch'] = """
# <form string="Daily Timebox">
# <field name="name" readonly="1"/>
# <notebook position="top">
# """
# for i in range(1,7):
# if not getattr(rec, 'context%d_id'%i):
# continue
# res['arch']+= """
# <page string="%s">
# <field name="%s" colspan="4" nolabel="1">
# <tree editable="bottom" colors="grey:state in ('done','pending');red:state=='cancelled'" string="Tasks">
# <field name="name"/>
# """ % (getattr(rec, 'context%d_id'%(i,)).name.encode('utf-8'), 'task%d_ids'%(i,))
# if rec.col_project:
# res['arch'] += '<field name="project_id" required="1"/>\n'
# if rec.col_date_start:
# res['arch'] += '<field name="date_start"/>\n'
# if rec.col_priority:
# res['arch'] += '<field name="priority"/>\n'
# if rec.col_deadline:
# res['arch'] += '<field name="date_deadline"/>\n'
# if rec.col_planned_hours:
# res['arch'] += '<field name="planned_hours" widget="float_time" sum="Est. Hours"/>\n'
# if rec.col_effective_hours:
# res['arch'] += '<field name="effective_hours" widget="float_time" sum="%s"/>\n' % (_('Eff. Hours'),)
# res['arch'] += """
# <field name="state" readonly="1"/>
# </tree>
# </field>
# </page>
# """
# res['arch']+="""
# </notebook>
# </form>
# """
# doc = etree.XML(res['arch'])
# xarch, xfields = self._view_look_dom_arch(cr, uid, doc, view_id, context=context)
# res['arch'] = xarch
# res['fields'] = xfields
# return res
project_gtd_timebox()
class project_task(osv.osv):
@@ -173,7 +115,6 @@ class project_task(osv.osv):
tt = timebox_obj.browse(cr, uid, timebox_obj.search(cr,uid,[]))
search_extended ='''<newline/><group col="%d" expand="0" string="%s" groups="project_gtd.group_project_getting">''' % (len(tt)+7,_('Getting Things Done'))
search_extended += '''<filter domain="[('timebox_id','=', False)]" context="{'set_editable':True,'set_visible':True,'gtd_visible':True}" icon="gtk-new" string="%s"/>''' % (_('Inbox'),)
# search_extended += '''<filter domain="[('state', 'in', ('draft','open','pending'))]" context="{'set_editable':True,'set_visible':True,'gtd_visible':True}" icon="gtk-new" string="%s"/>''' % (_('Editable'),)
search_extended += '''<separator orientation="vertical"/>'''
for time in tt:
if time.icon:
@@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv, fields
from tools.translate import _
+1
View File
@@ -23,4 +23,5 @@
import project_issue
import report
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -1
View File
@@ -20,7 +20,6 @@
#
##############################################################################
{
'name': 'Issue Management in Project Management',
'version': '1.0',
@@ -54,4 +53,5 @@
'installable': True,
'active': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+6 -7
View File
@@ -23,7 +23,6 @@ import base64
import os
import re
import time
import mx.DateTime
from datetime import datetime, timedelta
import binascii
import collections
@@ -101,8 +100,8 @@ class project_issue(osv.osv, crm.crm_case):
date_until = issue.date_open
#Calculating no. of working hours to open the issue
hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
mx.DateTime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'),
mx.DateTime.strptime(issue.date_open, '%Y-%m-%d %H:%M:%S'))
datetime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'),
datetime.strptime(issue.date_open, '%Y-%m-%d %H:%M:%S'))
elif field in ['working_hours_close','day_close']:
if issue.date_closed:
date_create = datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S")
@@ -111,8 +110,8 @@ class project_issue(osv.osv, crm.crm_case):
ans = date_close - date_create
#Calculating no. of working hours to close the issue
hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id,
mx.DateTime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'),
mx.DateTime.strptime(issue.date_closed, '%Y-%m-%d %H:%M:%S'))
datetime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'),
datetime.strptime(issue.date_closed, '%Y-%m-%d %H:%M:%S'))
if ans:
resource_id = False
if issue.user_id:
@@ -122,9 +121,9 @@ class project_issue(osv.osv, crm.crm_case):
duration = float(ans.days)
if issue.project_id and issue.project_id.resource_calendar_id:
duration = float(ans.days) * 24
new_dates = cal_obj.interval_min_get(cr, uid, issue.project_id.resource_calendar_id.id, mx.DateTime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'), duration, resource=resource_id)
new_dates = cal_obj.interval_min_get(cr, uid, issue.project_id.resource_calendar_id.id, datetime.strptime(issue.create_date, '%Y-%m-%d %H:%M:%S'), duration, resource=resource_id)
no_days = []
date_until = mx.DateTime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
for in_time, out_time in new_dates:
if in_time.date not in no_days:
no_days.append(in_time.date)
@@ -1,3 +1,25 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields,osv
import tools
from crm import crm
@@ -126,8 +148,7 @@ class project_issue_report(osv.osv):
project_issue c
WHERE c.categ_id IN (select res_id from ir_model_data WHERE model = 'crm.case.categ' and name='bug_categ')
)""")
project_issue_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="group_project_supporter" model="res.groups">
<field name="name">Project / Support Manager</field>
</record>
<record id="group_project_supporter" model="res.groups">
<field name="name">Project / Support Manager</field>
</record>
</data>
</openerp>
+1
View File
@@ -21,4 +21,5 @@
##############################################################################
import project_issue_sheet
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -1
View File
@@ -20,7 +20,6 @@
#
##############################################################################
{
'name': 'Add the Timesheet support for Issue Management in Project Management',
'version': '1.0',
@@ -44,4 +43,5 @@
'installable': True,
'active': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -1
View File
@@ -46,7 +46,6 @@
],
"update_xml": [
"security/ir.model.access.csv",
"project_long_term_wizard.xml" ,
"wizard/project_schedule_tasks_view.xml",
"project_long_term_view.xml",
"project_long_term_workflow.xml",
@@ -58,4 +57,5 @@
'active': False,
'certificate': None,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -18,9 +18,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from lxml import etree
import mx.DateTime
import time
from datetime import date, datetime, timedelta
from tools.translate import _
from osv import fields, osv
@@ -126,13 +126,12 @@ class project_phase(osv.osv):
def onchange_project(self, cr, uid, ids, project, context=None):
result = {}
result['date_start'] = False
project_obj = self.pool.get('project.project')
if project:
project_id = project_obj.browse(cr, uid, project, context=context)
if project_id.date_start:
result['date_start'] = mx.DateTime.strptime(project_id.date_start, "%Y-%m-%d").strftime('%Y-%m-%d')
return {'value': result}
return {'value': {'date_start': []}}
result['date_start'] = project_id.date_start
return {'value': result}
def _check_date_start(self, cr, uid, phase, date_end, context=None):
if context is None:
@@ -201,18 +200,17 @@ class project_phase(osv.osv):
calendar_id = cal_id
default_uom_id = self._get_default_uom_id(cr, uid)
avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
# Change the date_start and date_end
# for previous and next phases respectively based on valid condition
if vals.get('date_start', False) and vals['date_start'] < phase.date_start:
dt_start = mx.DateTime.strptime(vals['date_start'], '%Y-%m-%d')
dt_start = datetime.strptime(vals['date_start'], '%Y-%m-%d')
work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, dt_start, avg_hours or 0.0, resource_id and resource_id[0] or False)
if work_times:
vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d')
for prv_phase in phase.previous_phase_ids:
self._check_date_start(cr, uid, prv_phase, dt_start, context=context)
if vals.get('date_end', False) and vals['date_end'] > phase.date_end:
dt_end = mx.DateTime.strptime(vals['date_end'],'%Y-%m-%d')
dt_end = datetime.strptime(vals['date_end'], '%Y-%m-%d')
work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, dt_end, avg_hours or 0.0, resource_id and resource_id[0] or False)
if work_times:
vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d')
@@ -189,9 +189,6 @@
<field name="project_id" on_change="onchange_project(project_id)"/>
<field name="responsible_id"/>
<field name="date_start"/>
<!--<field name="date_end"/>
<field name="duration"/>
<field name="product_uom"/>-->
<field name="state"/>
</tree>
</field>
@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--<wizard id="wizard_compute_phase" menu="False" model="project.phase" name="wizard.compute.phases" string="Compute Phase Scheduling"/>-->
<!--<wizard id="wizard_schedule_task" menu="False" model="project.phase" name="phase.schedule.tasks" string="Schedule Tasks"/>-->
<!--<wizard id="wizard_compute_task" model="project.task" menu="False" name="wizard.compute.tasks" string="Compute Task Scheduling"/>-->
<!--<menuitem icon="terp-project" id="base.menu_main" name="Project Management" sequence="1"/>-->
<!--<menuitem id="base.menu_pm_planning" name="Planning" parent="base.menu_main" sequence="3"/>-->
<!-- <menuitem
action="wizard_compute_phase"
id="menu_wizard_compute_phase"
parent="base.menu_pm_planning"
type="wizard"
sequence="1"/>
-->
<!-- <menuitem
action="wizard_compute_task"
id="menu_wizard_compute_task"
parent="base.menu_pm_planning"
type="wizard"
sequence="1"/>
-->
</data>
</openerp>
@@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import datetime
from resource.faces import *
from new import classobj
@@ -139,4 +140,5 @@ class project_compute_tasks(osv.osv_memory):
return {}
project_compute_tasks()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import datetime
from resource.faces import *
from new import classobj
@@ -120,4 +120,5 @@ def compute_working_calendar(cr, uid, calendar_id, context=None):
if non_working:
wktime_cal.append((non_working[:-1], time_range))
return wktime_cal
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1
View File
@@ -37,4 +37,5 @@
'installable': True,
'active': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+23 -21
View File
@@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import mx.DateTime
from datetime import datetime, timedelta
import time
import math
@@ -46,17 +46,18 @@ class resource_calendar(osv.osv):
res_leaves = resource_cal_leaves.read(cr, uid, resource_leave_ids, ['date_from', 'date_to'])
for leave in res_leaves:
dtf = mx.DateTime.strptime(leave['date_from'], '%Y-%m-%d %H:%M:%S')
dtt = mx.DateTime.strptime(leave['date_to'], '%Y-%m-%d %H:%M:%S')
dtf = datetime.strptime(leave['date_from'], '%Y-%m-%d %H:%M:%S')
dtt = datetime.strptime(leave['date_to'], '%Y-%m-%d %H:%M:%S')
no = dtt - dtf
[dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))]
[dt_leave.append((dtf + timedelta(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))]
dt_leave.sort()
return dt_leave
def interval_min_get(self, cr, uid, id, dt_from, hours, resource=False):
if not id:
return [(dt_from - mx.DateTime.RelativeDateTime(hours=int(hours)*3), dt_from)]
td = int(hours)*3
return [(dt_from - timedelta(hours=td), dt_from)]
dt_leave = self._get_leaves(cr, uid, id, resource)
dt_leave.reverse()
todo = hours
@@ -65,7 +66,7 @@ class resource_calendar(osv.osv):
maxrecur = 100
current_hour = dt_from.hour
while (todo>0) and maxrecur:
cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from desc", (dt_from.day_of_week,id))
cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from desc", (dt_from.weekday(),id))
for (hour_from,hour_to) in cr.fetchall():
leave_flag = False
if (hour_from<current_hour) and (todo>0):
@@ -75,17 +76,17 @@ class resource_calendar(osv.osv):
dt_check = dt_from.strftime('%Y-%m-%d')
for leave in dt_leave:
if dt_check == leave:
dt_check = mx.DateTime.strptime(dt_check,"%Y-%m-%d") - mx.DateTime.RelativeDateTime(days=1)
dt_check = datetime.strptime(dt_check, '%Y-%m-%d') + timedelta(days=1)
leave_flag = True
if leave_flag:
break
else:
d1 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_from)), int((hour_from%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_from)), int((hour_from%1) * 60))
d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
result.append((d1, d2))
current_hour = hour_from
todo -= (m-hour_from)
dt_from -= mx.DateTime.RelativeDateTime(days=1)
dt_from -= timedelta(days=1)
current_hour = 24
maxrecur -= 1
result.reverse()
@@ -93,7 +94,8 @@ class resource_calendar(osv.osv):
def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True):
if not id:
return [(dt_from,dt_from + mx.DateTime.RelativeDateTime(hours=int(hours)*3))]
td = int(hours)*3
return [(dt_from, dt_from + timedelta(hours=td))]
dt_leave = self._get_leaves(cr, uid, id, resource)
todo = hours
cycle = 0
@@ -101,7 +103,7 @@ class resource_calendar(osv.osv):
maxrecur = 100
current_hour = dt_from.hour
while (todo>0) and maxrecur:
cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.day_of_week,id))
cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.weekday(),id))
for (hour_from,hour_to) in cr.fetchall():
leave_flag = False
if (hour_to>current_hour) and (todo>0):
@@ -111,17 +113,17 @@ class resource_calendar(osv.osv):
dt_check = dt_from.strftime('%Y-%m-%d')
for leave in dt_leave:
if dt_check == leave:
dt_check = mx.DateTime.strptime(dt_check, "%Y-%m-%d") + mx.DateTime.RelativeDateTime(days=1)
dt_check = datetime.strptime(dt_check, '%Y-%m-%d') + timedelta(days=1)
leave_flag = True
if leave_flag:
break
else:
d1 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
result.append((d1, d2))
current_hour = hour_to
todo -= (hour_to - m)
dt_from += mx.DateTime.RelativeDateTime(days=1)
dt_from += timedelta(days=1)
current_hour = 0
maxrecur -= 1
return result
@@ -136,7 +138,7 @@ class resource_calendar(osv.osv):
current_hour = dt_from.hour
while (dt_from <= dt_to):
cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.day_of_week,id))
cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.weekday(),id))
der = cr.fetchall()
for (hour_from,hour_to) in der:
if hours != 0.0:#For first time of the loop only,hours will be 0
@@ -146,24 +148,24 @@ class resource_calendar(osv.osv):
dt_check = dt_from.strftime('%Y-%m-%d')
for leave in dt_leave:
if dt_check == leave:
dt_check = mx.DateTime.strptime(dt_check, "%Y-%m-%d") + mx.DateTime.RelativeDateTime(days=1)
dt_check = datetime.strptime(dt_check, "%Y-%m-%d") + timedelta(days=1)
leave_flag = True
if leave_flag:
break
else:
d1 = dt_from
d2 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
if hours != 0.0:#For first time of the loop only,hours will be 0
d1 = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60))
d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60))
if dt_from.day == dt_to.day:
if hour_from <= dt_to.hour <= hour_to:
d2 = dt_to
dt_from = d2
hours += (d2-d1).seconds
dt_from = mx.DateTime.DateTime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60)) + mx.DateTime.RelativeDateTime(days=1)
dt_from = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60)) + timedelta(days=1)
current_hour = 0.0
return (hours/3600)