Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sao/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* Don't reset date/datetime/time to None when it is invalid

Version 6.4.8 - 2022-12-06
--------------------------
* Bug fixes (see mercurial logs for details)
Expand Down
28 changes: 22 additions & 6 deletions sao/src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@
if (!date) {
return '';
}
if (!date.isValid()) {
return date.invalid_value;
}
return date.format(Sao.common.moment_format(format));
};

Expand All @@ -253,26 +256,31 @@
return number;
}
}
return 0;
return undefined;
};
return Sao.Time(getNumber('%H'), getNumber('%M'), getNumber('%S'),
getNumber('%f'));
getNumber('%f'), value);
};

Sao.common.format_date = function(date_format, date) {
if (!date) {
return '';
}
if (!date.isValid()) {
return date.invalid_value;
}
return date.format(Sao.common.moment_format(date_format));
};

Sao.common.parse_date = function(date_format, value) {
var date = moment(value,
Sao.common.moment_format(date_format));
if (!value) {
return null;
}
var date = moment(value, Sao.common.moment_format(date_format));
if (date.isValid()) {
date = Sao.Date(date.year(), date.month(), date.date());
} else {
date = null;
date = Sao.Date(undefined, undefined, undefined, false, value);
}
return date;
};
Expand All @@ -281,17 +289,25 @@
if (!date) {
return '';
}
if (!date.isValid()) {
return date.invalid_value;
}
return date.format(Sao.common.moment_format(datetime_format));
};

Sao.common.parse_datetime = function(datetime_format, value) {
if (!value) {
return null;
}
var date = moment(value, Sao.common.moment_format(datetime_format));
if (date.isValid()) {
date = Sao.DateTime(date.year(), date.month(), date.date(),
date.hour(), date.minute(), date.second(),
date.millisecond());
} else {
date = null;
date = Sao.DateTime(undefined, undefined, undefined,
undefined, undefined, undefined, undefined,
false, false, value);
}
return date;
};
Expand Down
54 changes: 54 additions & 0 deletions sao/src/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,13 @@
time_format: function(record) {
return record.expr_eval(this.description.format);
},
get_eval: function() {
var value = Sao.field.DateTime._super.get_eval.call(this);
if (!value.isValid()) {
value = null;
}
return value;
},
set_client: function(record, value, force_change) {
var current_value;
if (value) {
Expand All @@ -1810,11 +1817,29 @@
date_format: function(record) {
var context = this.get_context(record);
return Sao.common.date_format(context.date_format);
},
validate: function(record, softvalidation, pre_validate) {
var valid = Sao.field.DateTime._super.validate.call(
this, record, softvalidation, pre_validate);
var state_attrs = this.get_state_attrs(record);
var value = this.get(record);
if (value && !value.isValid()) {
state_attrs.invalid = 'value';
valid = false;
}
return valid;
}
});

Sao.field.Date = Sao.class_(Sao.field.Field, {
_default: null,
get_eval: function() {
var value = Sao.field.DateTime._super.get_eval.call(this);
if (!value.isValid()) {
value = null;
}
return value;
},
set_client: function(record, value, force_change) {
if (value && !value.isDate) {
value.isDate = true;
Expand All @@ -1826,6 +1851,17 @@
date_format: function(record) {
var context = this.get_context(record);
return Sao.common.date_format(context.date_format);
},
validate: function(record, softvalidation, pre_validate) {
var valid = Sao.field.DateTime._super.validate.call(
this, record, softvalidation, pre_validate);
var state_attrs = this.get_state_attrs(record);
var value = this.get(record);
if (value && !value.isValid()) {
state_attrs.invalid = 'value';
valid = false;
}
return valid;
}
});

Expand All @@ -1834,13 +1870,31 @@
time_format: function(record) {
return record.expr_eval(this.description.format);
},
get_eval: function() {
var value = Sao.field.DateTime._super.get_eval.call(this);
if (!value.isValid()) {
value = null;
}
return value;
},
set_client: function(record, value, force_change) {
if (value && (value.isDate || value.isDateTime)) {
value = Sao.Time(value.hour(), value.minute(),
value.second(), value.millisecond());
}
Sao.field.Time._super.set_client.call(this, record, value,
force_change);
},
validate: function(record, softvalidation, pre_validate) {
var valid = Sao.field.Time._super.validate.call(
this, record, softvalidation, pre_validate);
var state_attrs = this.get_state_attrs(record);
var value = this.get(record);
if (value && !value.isValid()) {
state_attrs.invalid = 'value';
valid = false;
}
return valid;
}
});

Expand Down
32 changes: 25 additions & 7 deletions sao/src/sao.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,12 @@ var Sao = {};
}
};

Sao.Date = function(year, month, day) {
Sao.Date = function(year, month, day, valid=true, value=null) {
var date;
if (month === undefined) {
if (!valid) {
date = moment.invalid();
date.invalid_value = value;
} else if (month === undefined) {
date = moment(year);
year = undefined;
}
Expand All @@ -266,9 +269,13 @@ var Sao = {};

Sao.DateTime = function(
year, month, day,
hour=0, minute=0, second=0, millisecond=0, utc=false) {
hour=0, minute=0, second=0, millisecond=0, utc=false,
valid=true, value=null) {
var datetime;
if (month === undefined) {
if (!valid) {
datetime = moment.invalid();
datetime.invalid_value = value;
} else if (month === undefined) {
datetime = moment(year);
year = undefined;
}
Expand Down Expand Up @@ -310,9 +317,20 @@ var Sao = {};
Sao.DateTime.max = moment(new Date(100000000 * 86400000)).local();
Sao.DateTime.max.isDateTime = true;

Sao.Time = function(hour, minute, second, millisecond) {
var time = moment({hour: hour, minute: minute, second: second,
millisecond: millisecond || 0});
Sao.Time = function(hour, minute, second, millisecond, value=null) {
var time;
if ((hour === undefined) && (minute === undefined) &&
(second === undefined) && (millisecond === undefined)) {
time = moment.invalid();
} else {
time = moment({
hour: hour, minute: minute, second: second,
millisecond: millisecond || 0
});
}
if (!time.isValid()) {
time.invalid_value = value;
}
time.isTime = true;
return time;
};
Expand Down
3 changes: 3 additions & 0 deletions sao/src/screen.js
Original file line number Diff line number Diff line change
Expand Up @@ -1889,6 +1889,9 @@
} else if (invalid == 'children') {
fields.push(Sao.i18n.gettext(
'The values of "%1" are not valid.', string));
} else if (invalid == 'value') {
fields.push(Sao.i18n.gettext(
'The value of "%1" is not valid.', string));
} else {
if (domain_parser.stringable(invalid)) {
fields.push(domain_parser.string(invalid));
Expand Down
36 changes: 33 additions & 3 deletions sao/src/view/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2047,7 +2047,15 @@ function eval_pyson(value){
'name': attributes.name,
}).appendTo(group);
this.date.uniqueId();
this.date.on('keydown', this.send_modified.bind(this));
this.date.on('keydown', () => {
var value = this.get_value();
if (value && !value.isValid()) {
this._invalid_el().addClass('has-error');
} else {
this._invalid_el().removeClass('has-error');
}
this.send_modified();
});
this.input = jQuery('<input/>', {
'type': this._input,
'role': 'button',
Expand Down Expand Up @@ -2136,11 +2144,33 @@ function eval_pyson(value){
if (this.record && this.field) {
var field_value = this.cast(
this.field.get_client(this.record));
return (JSON.stringify(field_value) !=
JSON.stringify(this.get_value()));
return this._cmp(field_value, this.get_value());
}
return false;
},
send_modified: function() {
window.setTimeout(() => {
var value = this.get_value();
window.setTimeout(() => {
if (this.record &&
this._cmp(this.get_value(), value) &&
this.modified) {
this.view.screen.record_modified(false);
}
}, 300);
});
},
_cmp: function(dt1, dt2) {
if ((dt1 && !dt1.isValid()) &&
(dt2 && !dt2.isValid())) {
return dt1.invalid_value != dt2.invalid_value;
} else if ((dt1 && !dt1.isValid()) ||
(dt2 && !dt2.isValid())) {
return true;
} else {
return JSON.stringify(dt1) != JSON.stringify(dt2);
}
},
set_value: function() {
this.field.set_client(this.record, this.get_value());
},
Expand Down
45 changes: 36 additions & 9 deletions sao/tests/sao.js
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,28 @@
JSON.stringify(value) + ', ' + JSON.stringify(context) + ')');
};

var test_moment_func = function(test) {
var value = test[0];
var result = test[1];

var compare = function(d1, d2) {
if ((d1 && d1.isValid()) && (d2 && d2.isValid())) {
return d1.valueOf() === d2.valueOf();
} else if ((d1 && !d1.isValid()) && (d2 && !d2.isValid())) {
return d1.invalid_value === d2.invalid_value;
} else if (!d1 && !d2) {
return d1 === d2;
} else {
return false;
}
};

QUnit.ok(compare(
parser.convert_value(this, value, context), result),
'convert_value(' + JSON.stringify(this)+ ', ' +
JSON.stringify(value)+ ', ' + JSON.stringify(context) + ')');
};

var field = {
'type': 'boolean'
};
Expand Down Expand Up @@ -1757,34 +1779,39 @@
[
['2002-12-04', Sao.DateTime(2002, 11, 4)],
['2002-12-04 12:30:00', Sao.DateTime(2002, 11, 4, 12, 30)]
].forEach(test_valueOf_func, field);
].forEach(test_moment_func, field);
[
['test', null],
['test', Sao.DateTime(
undefined, undefined, undefined,
undefined, undefined, undefined, undefined, false,
false, 'test')],
[null, null]
].forEach(test_func, field);
].forEach(test_moment_func, field);

field = {
'type': 'date'
};
[
['2002-12-04', Sao.Date(2002, 11, 4)]
].forEach(test_valueOf_func, field);
].forEach(test_moment_func, field);
[
['test', null],
['test', Sao.Date(
undefined, undefined, undefined,
false, 'test')],
[null, null]
].forEach(test_func, field);
].forEach(test_moment_func, field);

field = {
'type': 'time',
'format': '"%H:%M:%S"'
};
[
['12:30:00', Sao.Time(12, 30, 0)],
['test', Sao.Time(0, 0, 0)]
].forEach(test_valueOf_func, field);
['test', Sao.Time(undefined, undefined, undefined, undefined, 'test')]
].forEach(test_moment_func, field);
[
[null, null]
].forEach(test_func, field);
].forEach(test_moment_func, field);

field = {
'type': 'timedelta'
Expand Down
2 changes: 2 additions & 0 deletions tryton/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* Don't reset date/datetime/time to None when it is invalid

Version 6.4.6 - 2022-11-17
--------------------------
* Bug fixes (see mercurial logs for details)
Expand Down
Loading