details: https://code.openbravo.com/erp/devel/pi/rev/976c8398def2
changeset: 16806:976c8398def2
user: Augusto Mauch <augusto.mauch <at> openbravo.com>
date: Tue Jun 12 11:24:28 2012 +0200
summary: Fixes issue 20684: Time fields are passed in UTC format
The problem was due to:
- Time fields were not being passed between client and server in UTC format
- When constructing a date based on a time (i.e. 10:00:00), the date used was
1970-01-01. This way, it was not possible to convert from UTC to local hour,
because the DST offset depends
on the date.
It has been fixed by:
- Sending the time fields in UTC format. Upon receiving a time field,
converting it to local time.
- Upon receiving a time field, creating a new date using todays date instead of
1970-01-01
: Enter commit message. Lines beginning with 'HG:' are removed.
diffstat:
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-time.js
| 23 +++-
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js
| 46 ++++++-
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js
| 48 ++++++-
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js
| 27 +++-
modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/TimeUIDefinition.java
| 72 +++++++++-
modules/org.openbravo.service.json/src/org/openbravo/service/json/DataToJsonConverter.java
| 25 +++-
modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonToDataConverter.java
| 20 ++-
modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonUtils.java
| 10 +
8 files changed, 256 insertions(+), 15 deletions(-)
diffs (truncated from 435 to 300 lines):
diff -r a6672f4c6903 -r 976c8398def2
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-time.js
---
a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-time.js
Tue Jun 12 10:18:59 2012 +0200
+++
b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-time.js
Tue Jun 12 11:24:28 2012 +0200
@@ -59,6 +59,27 @@
if (isc.isA.String(value) && (value.contains('+') || value.contains('-')))
{
value = isc.Time.parseInput(value, null, null, true);
}
+ if (value && isc.isA.String(value)) {
+ value = isc.Time.parseInput(value);
+ }
+ if (value && isc.isA.Date(value)) {
+ this.setTodaysDate(value);
+ }
return this.Super('setValue', arguments);
- }
+ },
+
+ getValue: function () {
+ var value = this.Super('getValue', arguments);
+ if (value && isc.isA.Date(value)) {
+ this.setTodaysDate(value);
+ }
+ return value;
+ },
+
+ setTodaysDate: function(date) {
+ var today = new Date();
+ date.setYear(today.getFullYear());
+ date.setMonth(today.getMonth());
+ date.setDate(today.getDate());
+ }
});
\ No newline at end of file
diff -r a6672f4c6903 -r 976c8398def2
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js
---
a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js
Tue Jun 12 10:18:59 2012 +0200
+++
b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js
Tue Jun 12 11:24:28 2012 +0200
@@ -182,10 +182,20 @@
}
},
- editRecord: function (record, preventFocus, hasChanges, focusFieldName) {
+ editRecord: function (record, preventFocus, hasChanges, focusFieldName,
isLocalTime) {
+ var timeFields, ret;
this.clearValues();
+ // if editRecord is called from OBStandardView.editRecord, then the time
fields have already
+ // be converted from UTC to local time
+ // if editRecord is called from fetchDataReply (ActionMethod.js) then the
record comes directly
+ // from the datasource, so it has to be converted from UTC to local time
+ // see issue https://issues.openbravo.com/view.php?id=20684
+ if (!isLocalTime) {
+ timeFields = this.getTimeFields();
+ this.convertUTCTimeToLocalTime(record, timeFields);
+ }
- var ret = this.Super('editRecord', arguments);
+ ret = this.Super('editRecord', arguments);
// used when clicking on a cell in a grid
if (!preventFocus && focusFieldName) {
@@ -248,6 +258,38 @@
}
},
+ getTimeFields: function () {
+ var i, field, timeFields = [],
+ length = this.fields.length;
+ for (i = 0; i < length; i++) {
+ field = this.fields[i];
+ if (field.type === '_id_24') {
+ timeFields.push(field.name);
+ }
+ }
+ return timeFields;
+ },
+
+ convertUTCTimeToLocalTime: function (record, timeFields) {
+ var textField, fieldToDate, i, localHour
+ timeFieldsLength = timeFields.length,
+ UTCOffset = isc.Time.getUTCHoursDisplayOffset(new Date());
+ for (i = 0; i < timeFieldsLength; i++) {
+ textField = record[timeFields[i]];
+ if (textField && textField.length > 0) {
+ fieldToDate = isc.Time.parseInput(textField);
+ localHour = fieldToDate.getHours() + UTCOffset;
+ if (localHour > 23) {
+ localHour = localHour - 24;
+ } else if (localHour < 0) {
+ localHour = localHour + 24;
+ }
+ // TODO: support time formats other than HH:mm:ss
+ record[timeFields[i]] = '' + localHour + ':' +
fieldToDate.getMinutes() + ':' + fieldToDate.getSeconds();
+ }
+ }
+ },
+
editNewRecord: function (preventFocus) {
this.clearValues();
var ret = this.Super('editNewRecord', arguments);
diff -r a6672f4c6903 -r 976c8398def2
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js
---
a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js
Tue Jun 12 10:18:59 2012 +0200
+++
b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js
Tue Jun 12 11:24:28 2012 +0200
@@ -198,10 +198,17 @@
},
transformData: function (newData, dsResponse) {
- var i, length;
-
+ var i, length, timeFields;
+
+ // when the data is received from the datasource, time fields are
formatted in UTC time. They have to be converted to local time
+ if (dsResponse && dsResponse.context &&
(dsResponse.context.operationType === 'fetch' ||
dsResponse.context.operationType === 'update' ||
dsResponse.context.operationType === 'add')) {
+ if (this.grid) {
+ timeFields = this.grid.getTimeFields();
+ this.grid.convertUTCTimeToLocalTime(newData, timeFields);
+ }
+ }
// only do this stuff for fetch operations, in other cases strange things
- // happen as update/delete operations do not return the totalRows
parameter
+ // happen as update/delete operations do not return the totalRows
parameter
if (dsResponse && dsResponse.context && dsResponse.context.operationType
!== 'fetch') {
return;
}
@@ -228,6 +235,41 @@
}
},
+ // returns the name of all time fields (type = '_id_24')
+ getTimeFields: function () {
+ var i, field, timeFields = [],
+ length = this.completeFields.length;
+ for (i = 0; i < length; i++) {
+ field = this.completeFields[i];
+ if (field.type === '_id_24') {
+ timeFields.push(field.name);
+ }
+ }
+ return timeFields;
+ },
+
+ convertUTCTimeToLocalTime: function (newData, timeFields) {
+ var textField, fieldToDate, i, j, localHour
+ timeFieldsLength = timeFields.length,
+ newDataLength = newData.length,
+ UTCOffset = isc.Time.getUTCHoursDisplayOffset(new Date());
+ for (i = 0; i < timeFieldsLength; i++) {
+ for (j = 0; j < newDataLength; j++) {
+ textField = newData[j][timeFields[i]];
+ if (textField && textField.length > 0) {
+ fieldToDate = isc.Time.parseInput(textField);
+ localHour = fieldToDate.getHours() + UTCOffset;
+ if (localHour > 23) {
+ localHour = localHour - 24;
+ } else if (localHour < 0) {
+ localHour = localHour + 24;
+ }
+ newData[j][timeFields[i]] = '' + localHour + ':' +
fieldToDate.getMinutes() + ':' + fieldToDate.getSeconds();
+ }
+ }
+ }
+ },
+
initWidget: function () {
var i, vwState;
diff -r a6672f4c6903 -r 976c8398def2
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js
---
a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js
Tue Jun 12 10:18:59 2012 +0200
+++
b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js
Tue Jun 12 11:24:28 2012 +0200
@@ -1017,7 +1017,9 @@
// Opens the edit form and selects the record in the grid, will refresh
// child views also
editRecord: function (record, preventFocus, focusFieldName) {
-
+ var rowNum,
+ // at this point the time fields of the record are formatted in local time
+ localTime = true;
this.messageBar.hide();
if (!this.isShowingForm) {
@@ -1033,8 +1035,8 @@
// also handle the case that there are unsaved values in the grid
// show them in the form
- var rowNum = this.viewGrid.getRecordIndex(record);
- this.viewForm.editRecord(this.viewGrid.getEditedRecord(rowNum),
preventFocus, this.viewGrid.recordHasChanges(rowNum), focusFieldName);
+ rowNum = this.viewGrid.getRecordIndex(record);
+ this.viewForm.editRecord(this.viewGrid.getEditedRecord(rowNum),
preventFocus, this.viewGrid.recordHasChanges(rowNum), focusFieldName,
localTime);
}
},
@@ -1892,13 +1894,30 @@
},
convertContextValue: function (value, type) {
- var isTime = isc.isA.Date(value) && type &&
isc.SimpleType.getType(type).inheritsFrom === 'time';
+ var isTime;
+ // if a string is received, it is converted to a date so that the function
+ // is able to return its UTC time in the HH:mm:ss format
+ if (isc.isA.String(value) && value.length > 0 && type &&
isc.SimpleType.getType(type).inheritsFrom === 'time') {
+ value = this.convertToDate(value);
+ }
+ isTime = isc.isA.Date(value) && type &&
isc.SimpleType.getType(type).inheritsFrom === 'time';
if (isTime) {
return value.getUTCHours() + ':' + value.getUTCMinutes() + ':' +
value.getUTCSeconds();
}
return value;
},
+ convertToDate: function (stringValue) {
+ var today = new Date(),
+ dateValue = isc.Time.parseInput(stringValue);
+ // Only the time is relevant. In order to be able to convert it from UTC
to local time
+ // properly the date value should be today's date
+ dateValue.setYear(today.getFullYear());
+ dateValue.setMonth(today.getMonth());
+ dateValue.setDate(today.getDate());
+ return dateValue;
+ },
+
getPropertyDefinition: function (property) {
var properties = this.propertyToColumns,
i, length = properties.length;
diff -r a6672f4c6903 -r 976c8398def2
modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/TimeUIDefinition.java
---
a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/TimeUIDefinition.java
Tue Jun 12 10:18:59 2012 +0200
+++
b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/TimeUIDefinition.java
Tue Jun 12 11:24:28 2012 +0200
@@ -18,10 +18,19 @@
*/
package org.openbravo.client.kernel.reference;
+import java.text.FieldPosition;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
import org.openbravo.base.exception.OBException;
import org.openbravo.base.session.OBPropertiesProvider;
+import org.openbravo.client.kernel.RequestContext;
+import org.openbravo.data.Sqlc;
+import org.openbravo.model.ad.ui.Field;
import org.openbravo.service.json.JsonUtils;
/**
@@ -66,16 +75,75 @@
return classicFormat;
}
+ // getFieldProperties has to be overridden because depending on the value of
getValueFromSession,
+ // time fields have to be converted from localTime to UTC before sending the
to the client
@Override
+ public String getFieldProperties(Field field, boolean getValueFromSession) {
+ String result = super.getFieldProperties(field, getValueFromSession);
+ try {
+ JSONObject jsnobject = new JSONObject(result);
+ if (getValueFromSession) {
+ RequestContext rq = RequestContext.get();
+ String columnValue = rq.getRequestParameter("inp"
+ +
Sqlc.TransformaNombreColumna(field.getColumn().getDBColumnName()));
+ if (columnValue.isEmpty()) {
+ // If the date is empty, it does not have to be converted
+ return result;
+ }
+ // createFromClassicString has been called with an UTC date, it
expects a date in local
+ // time,
+ // so the time is going to be converted to local time, and going to be
passed to
+ // createFromClassicString
+ Date UTCDate = getClassicFormat().parse(columnValue);
+ Calendar now = Calendar.getInstance();
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(UTCDate);
+ calendar.set(Calendar.DATE, now.get(Calendar.DATE));
+ calendar.set(Calendar.MONTH, now.get(Calendar.MONTH));
+ calendar.set(Calendar.YEAR, now.get(Calendar.YEAR));
+
+ int gmtHourOffset = (now.get(Calendar.ZONE_OFFSET) +
now.get(Calendar.DST_OFFSET))
+ / (1000 * 60 * 60);
+ calendar.add(Calendar.HOUR, gmtHourOffset);
+ StringBuffer localTimeColumnValue =
getClassicFormat().format(calendar.getTime(),
+ new StringBuffer(), new FieldPosition(0));
+ jsnobject.put("value",
createFromClassicString(localTimeColumnValue.toString()));
+ jsnobject.put("classicValue", localTimeColumnValue.toString());
+ return jsnobject.toString();
+ }
+ } catch (JSONException e) {
+ throw new OBException("Exception when parsing date ", e);
+ } catch (ParseException e) {
+ throw new OBException("Exception when parsing date ", e);
+ }
+ return result;
+ }
+
+ @Override
+ // Value is a date in local time format
public synchronized Object createFromClassicString(String value) {
try {
if (value == null || value.length() == 0 || value.equals("null")) {
return null;
}
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Openbravo-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openbravo-commits