Skip to content

Commit

Permalink
[FIX] spreadsheet: update o_spreadsheet to latest version
Browse files Browse the repository at this point in the history
odoo/o-spreadsheet@7251a4753 [REL] 16.0.28
odoo/o-spreadsheet@8ec11bb59 [FIX] Cell: Fix detection of markdown links Task: 3628780
odoo/o-spreadsheet@eb8775d0d [FIX] dates: use UTC to represent naive date times Task: 3666703
odoo/o-spreadsheet@006170031 [REF] dates: introduce DateTime to wrap Date object Task: 3666703
odoo/o-spreadsheet@a27b13683 [FIX] date: properly type reference dates Task: 3666703

closes odoo#149232

Signed-off-by: Rémi Rahir (rar) <rar@odoo.com>
  • Loading branch information
LucasLefevre committed Jan 16, 2024
1 parent 9786696 commit 7a46010
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 48 deletions.
6 changes: 1 addition & 5 deletions addons/spreadsheet/static/src/helpers/helpers.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/** @odoo-module */

import { serializeDate } from "@web/core/l10n/dates";
import { loadJS } from "@web/core/assets";

const { DateTime } = luxon;

/**
* Get the intersection of two arrays
*
Expand Down Expand Up @@ -50,8 +47,7 @@ export function orderByToString(orderBy) {
* @returns {string}
*/
export function toServerDateString(value) {
const date = DateTime.fromJSDate(value);
return serializeDate(date);
return `${value.getFullYear()}-${value.getMonth() + 1}-${value.getDate()}`;
}

/**
Expand Down
140 changes: 100 additions & 40 deletions addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,76 @@
// -----------------------------------------------------------------------------
// Date Type
// -----------------------------------------------------------------------------
/**
* A DateTime object that can be used to manipulate spreadsheet dates.
* Conceptually, a spreadsheet date is simply a number with a date format,
* and it is timezone-agnostic.
* This DateTime object consistently uses UTC time to represent a naive date and time.
*/
class DateTime {
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
}
static fromTimestamp(timestamp) {
const date = new Date(timestamp);
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}
static now() {
const now = new Date();
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
}
toString() {
return this.jsDate.toString();
}
getTime() {
return this.jsDate.getTime();
}
getFullYear() {
return this.jsDate.getUTCFullYear();
}
getMonth() {
return this.jsDate.getUTCMonth();
}
getDate() {
return this.jsDate.getUTCDate();
}
getDay() {
return this.jsDate.getUTCDay();
}
getHours() {
return this.jsDate.getUTCHours();
}
getMinutes() {
return this.jsDate.getUTCMinutes();
}
getSeconds() {
return this.jsDate.getUTCSeconds();
}
setFullYear(year) {
this.jsDate.setFullYear(year);
}
setDate(date) {
this.jsDate.setUTCDate(date);
}
setHours(hours) {
this.jsDate.setUTCHours(hours);
}
setMinutes(minutes) {
this.jsDate.setUTCMinutes(minutes);
}
setSeconds(seconds) {
this.jsDate.setUTCSeconds(seconds);
}
}
// -----------------------------------------------------------------------------
// Parsing
// -----------------------------------------------------------------------------
const INITIAL_1900_DAY = new Date(1899, 11, 30);
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
const MS_PER_DAY = 24 * 60 * 60 * 1000;
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
const CURRENT_YEAR = new Date().getFullYear();
const INITIAL_JS_DAY = new Date(0);
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
const CURRENT_YEAR = DateTime.now().getFullYear();
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
Expand Down Expand Up @@ -361,7 +422,7 @@
return {
value: date.value + time.value,
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
jsDate: new Date(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
jsDate: new DateTime(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
};
}
return date || time;
Expand All @@ -378,13 +439,13 @@
const day = Number(parts[dayIndex]);
const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
const jsDate = new Date(year, month - 1, day);
const jsDate = new DateTime(year, month - 1, day);
const sep = str.match(/\/|-|\s/)[0];
if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
// invalid date
return null;
}
const delta = jsDate - INITIAL_1900_DAY;
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
if (parts[yearIndex]) {
format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
Expand Down Expand Up @@ -444,7 +505,7 @@
if (hours >= 24) {
format = "hhhh:mm:ss";
}
const jsDate = new Date(1899, 11, 30, hours, minutes, seconds);
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
return {
value: hours / 24 + minutes / 1440 + seconds / 86400,
format: format,
Expand All @@ -458,7 +519,7 @@
// -----------------------------------------------------------------------------
function numberToJsDate(value) {
const truncValue = Math.trunc(value);
let date = new Date(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
let time = value - truncValue;
time = time < 0 ? 1 + time : time;
const hours = Math.round(time * 24);
Expand All @@ -475,7 +536,7 @@
}
/** Return the number of days in the current month of the given date */
function getDaysInMonth(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
}
function isLastDayOfMonth(date) {
return getDaysInMonth(date) === date.getDate();
Expand All @@ -493,7 +554,7 @@
const yStart = date.getFullYear();
const mStart = date.getMonth();
const dStart = date.getDate();
const jsDate = new Date(yStart, mStart + months);
const jsDate = new DateTime(yStart, mStart + months, 1);
if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
jsDate.setDate(getDaysInMonth(jsDate));
}
Expand Down Expand Up @@ -846,7 +907,7 @@
function isDateTime(str) {
return parseDateTime(str) !== null;
}
const MARKDOWN_LINK_REGEX = /^\[([^\[]+)\]\((.+)\)$/;
const MARKDOWN_LINK_REGEX = /^\[(.+)\]\((.+)\)$/;
//link must start with http or https
//https://stackoverflow.com/a/3809435/4760614
const WEB_LINK_REGEX = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;
Expand Down Expand Up @@ -1769,7 +1830,7 @@
.map((p) => {
switch (p) {
case "hhhh":
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
return helapsedHours.toString();
case "hh":
return hours.toString().padStart(2, "0");
Expand Down Expand Up @@ -13845,7 +13906,7 @@
if (_year < 1900) {
_year += 1900;
}
const jsDate = new Date(_year, _month - 1, _day);
const jsDate = new DateTime(_year, _month - 1, _day);
const result = jsDateToRoundNumber(jsDate);
assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
return result;
Expand Down Expand Up @@ -13957,7 +14018,7 @@
const _months = Math.trunc(toNumber(months));
const yStart = _startDate.getFullYear();
const mStart = _startDate.getMonth();
const jsDate = new Date(yStart, mStart + _months + 1, 0);
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
return jsDateToRoundNumber(jsDate);
},
isExported: true,
Expand Down Expand Up @@ -13996,17 +14057,17 @@
// The first week of the year is the week that contains the first
// Thursday of the year.
let firstThursday = 1;
while (new Date(y, 0, firstThursday).getDay() !== 4) {
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
firstThursday += 1;
}
const firstDayOfFirstWeek = new Date(y, 0, firstThursday - 3);
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
// The last week of the year is the week that contains the last Thursday of
// the year.
let lastThursday = 31;
while (new Date(y, 11, lastThursday).getDay() !== 4) {
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
lastThursday -= 1;
}
const lastDayOfLastWeek = new Date(y, 11, lastThursday + 3);
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
let offsetYear;
Expand All @@ -14032,17 +14093,17 @@
case 1:
// firstDay is the 1st day of the 1st week of the year after
// firstDay = lastDayOfLastWeek + 1 Day
firstDay = new Date(y, 11, lastThursday + 3 + 1);
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
break;
case -1:
// firstDay is the 1st day of the 1st week of the previous year.
// The first week of the previous year is the week that contains the
// first Thursday of the previous year.
let firstThursdayPreviousYear = 1;
while (new Date(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
firstThursdayPreviousYear += 1;
}
firstDay = new Date(y - 1, 0, firstThursdayPreviousYear - 3);
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
break;
}
const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
Expand Down Expand Up @@ -14181,8 +14242,8 @@
});
}
const invertDate = _startDate.getTime() > _endDate.getTime();
const stopDate = new Date((invertDate ? _startDate : _endDate).getTime());
let stepDate = new Date((invertDate ? _endDate : _startDate).getTime());
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
const timeStopDate = stopDate.getTime();
let timeStepDate = stepDate.getTime();
let netWorkingDay = 0;
Expand All @@ -14206,8 +14267,7 @@
returns: ["DATE"],
computeFormat: () => "m/d/yyyy hh:mm:ss",
compute: function () {
let today = new Date();
today.setMilliseconds(0);
let today = DateTime.now();
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
return Math.floor(delta / MS_PER_DAY) + time;
Expand Down Expand Up @@ -14281,8 +14341,8 @@
returns: ["DATE"],
computeFormat: () => "m/d/yyyy",
compute: function () {
const today = new Date();
const jsDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
const today = DateTime.now();
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
return jsDateToRoundNumber(jsDate);
},
isExported: true,
Expand Down Expand Up @@ -14337,10 +14397,10 @@
}
const y = _date.getFullYear();
let dayStart = 1;
let startDayOfFirstWeek = new Date(y, 0, dayStart);
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
dayStart += 1;
startDayOfFirstWeek = new Date(y, 0, dayStart);
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
}
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
if (dif < 0) {
Expand Down Expand Up @@ -14394,7 +14454,7 @@
timesHoliday.add(holiday.getTime());
});
}
let stepDate = new Date(_startDate.getTime());
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
let timeStepDate = stepDate.getTime();
const unitDay = Math.sign(_numDays);
let stepDay = Math.abs(_numDays);
Expand Down Expand Up @@ -14460,7 +14520,7 @@
const _startDate = toJsDate(date);
const yStart = _startDate.getFullYear();
const mStart = _startDate.getMonth();
const jsDate = new Date(yStart, mStart, 1);
const jsDate = new DateTime(yStart, mStart, 1);
return jsDateToRoundNumber(jsDate);
},
};
Expand Down Expand Up @@ -14504,7 +14564,7 @@
compute: function (date) {
const quarter = QUARTER.compute(date);
const year = YEAR.compute(date);
const jsDate = new Date(year, (quarter - 1) * 3, 1);
const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
return jsDateToRoundNumber(jsDate);
},
};
Expand All @@ -14521,7 +14581,7 @@
compute: function (date) {
const quarter = QUARTER.compute(date);
const year = YEAR.compute(date);
const jsDate = new Date(year, quarter * 3, 0);
const jsDate = new DateTime(year, quarter * 3, 0);
return jsDateToRoundNumber(jsDate);
},
};
Expand All @@ -14537,7 +14597,7 @@
computeFormat: () => "m/d/yyyy",
compute: function (date) {
const year = YEAR.compute(date);
const jsDate = new Date(year, 0, 1);
const jsDate = new DateTime(year, 0, 1);
return jsDateToRoundNumber(jsDate);
},
};
Expand All @@ -14553,7 +14613,7 @@
computeFormat: () => "m/d/yyyy",
compute: function (date) {
const year = YEAR.compute(date);
const jsDate = new Date(year + 1, 0, 0);
const jsDate = new DateTime(year + 1, 0, 0);
return jsDateToRoundNumber(jsDate);
},
};
Expand Down Expand Up @@ -14687,7 +14747,7 @@
function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
const startDate = toJsDate(settlement);
const endDate = toJsDate(maturity);
const startDatePlusOneYear = new Date(startDate);
const startDatePlusOneYear = toJsDate(settlement);
startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
}
Expand Down Expand Up @@ -43070,9 +43130,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
Object.defineProperty(exports, '__esModule', { value: true });


__info__.version = '16.0.27';
__info__.date = '2024-01-04T12:42:45.292Z';
__info__.hash = '54006f6';
__info__.version = '16.0.28';
__info__.date = '2024-01-12T13:53:29.864Z';
__info__.hash = '7251a47';


})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
Expand Down
6 changes: 3 additions & 3 deletions addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3256,7 +3256,7 @@ https://fontawesome.com/license -->
</t>
</odoo>
<!--
__info__.version = '16.0.27';
__info__.date = '2024-01-04T12:42:46.770Z';
__info__.hash = '54006f6';
__info__.version = '16.0.28';
__info__.date = '2024-01-12T13:53:35.814Z';
__info__.hash = '7251a47';
-->

0 comments on commit 7a46010

Please sign in to comment.