Change most Date fields by DateTime


(Cédric Krier) #1

Continuing the discussion from Pending State on Purchase Requests:
We usually use a date field to store the “date” (in speaking language) of the record but it is because we are thinking only about simple case (like sale date, stock move date etc.). If we want to make Tryton ready for more use-cases where the precision should be smaller than the day, we should use DateTime fields.
The idea is to replace those dates by a DateTime with by default no format for the time part like that it is transparent to the user (and the developer).
The opened question is how to deal with time-zone in this perspective because DateTime are stored in UTC?


(Sergio Morillo) #2

We had to implement a simple module[1] to get date and time in stock moves and shipments (for now only internal and out).
Generally we had no problem with UTC and time-zone conversion due to client converts pretty well the values, but there are some points which must be remark:

  • CSV exporting does not convert UTC date time to user time zone.
  • At programming level it’s difficult to deal with date and date time fields without information about user time zone. In our case (Spain), querying by standard way the stock of a product at a date will not return a correct stock if some movements where created by user with no time (they are saved in UTC, so the day/date stored is yesterday at 23:00:00).

IMHO user time zone could be cached in context, and ‘ir.date’ model could have a method to convert from TZ to UTC and viceversa.

[1] https://bitbucket.org/datalife_sco/trytond-stock_move_time


(Cédric Krier) #3

I think it is probably better when the need exists to just replace the date fields by datetime fields via a module. Normally now, most operation done on those dates are using DeltaTime which will work transparently for both type.
Of course such module should be carefully tested to ensure that no operation relies on the Date only feature. I think for example about code that compare with today which should probably convert to date in case (ex: Move.compute_quantities_query).


(Sergi Almacellas Abellana) #4

In case of using datetime shouldn’t the value be now instead of today?


(Cédric Krier) #5

Yes of course, this should be part of the extension module.
And even maybe it should have a configuration (ex: on warehouse) to pick a default time.


(Sergi Almacellas Abellana) #6

I’ve developed a module that changes the date field of account payment into a datetime field.

Here is the code needed to implement such change:

@classmethod                                                               
def __setup__(cls):                                                                                      
    super(Payment, cls).__setup__()                          
    # Override definition to change Date to DateTime                       
    cls.date = fields.DateTime(cls.date.string, help=cls.date.help,        
        required=cls.date.required)              
                                                                           
@classmethod                                                               
def default_date(cls):                                                     
    date = super(Payment, cls).default_date()                              
    return datetime.datetime.combine(date, datetime.datetime.now().time()) 
                                                                           
@classmethod                                                               
def _view_look_dom_arch(cls, tree, type, field_children=None):             
    # Override date field to use date widget on list                       
    if type == 'tree':                                                     
        elements = tree.xpath('//field[@name="date"]')                     
        for field in elements:                                             
            field.attrib['widget'] = 'date'                                
    return super(Payment, cls)._view_look_dom_arch(                        
        tree, type, field_children)

The only drawback that we found is that this breaks the sqlite as alter type is not suported by sqlite.


(Sergi Almacellas Abellana) #7

Indeed it’s a missing feature for sqlite. Opened issue6730 in order to support it on newer versions.


(Cédric Krier) #8

Why using __post_setup__ instead of __setup__? It is not supposed to be for public usage.


(Sergi Almacellas Abellana) #9

My fault, using __setup__ works, but you have to redifine the field after the supper call. I’m updating the code snippet.

Thanks for your feedback.