[REF] *:Replace moment usages with luxon
luxon and moment are both used in the solution, but these two libraries facilitate the manipulation of dates. It was decided to replace all uses of moment with luxon so we can then remove moment.js from the code and lighten the assets. task-3391739 closes odoo/odoo#128752 Signed-off-by: Bruno Boi (boi) <boi@odoo.com>
This commit is contained in:
@@ -6,6 +6,8 @@ import { registry } from "@web/core/registry";
|
||||
import { registerCleanup } from "@web/../tests/helpers/cleanup";
|
||||
import { makeMockServer } from "@web/../tests/helpers/mock_server";
|
||||
import core from "@web/legacy/js/services/core";
|
||||
import { serializeDateTime, serializeDate } from "@web/core/l10n/dates";
|
||||
const { DateTime } = luxon;
|
||||
|
||||
const modelDefinitionsPromise = new Promise((resolve) => {
|
||||
QUnit.begin(() => resolve(getModelDefinitions()));
|
||||
@@ -56,8 +58,8 @@ async function getModelDefinitions() {
|
||||
if (["date", "datetime"].includes(field.type) && !field.default) {
|
||||
const defaultFieldValue =
|
||||
field.type === "date"
|
||||
? () => moment.utc().format("YYYY-MM-DD")
|
||||
: () => moment.utc().format("YYYY-MM-DD HH:mm:ss");
|
||||
? () => serializeDate(DateTime.utc())
|
||||
: () => serializeDateTime(DateTime.utc());
|
||||
field.default = defaultFieldValue;
|
||||
} else if (fname === "active" && !("default" in field)) {
|
||||
// records are active by default.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import { ActivityMenu } from "@mail/core/web/activity_menu";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import fieldUtils from "@web/legacy/js/fields/field_utils";
|
||||
import time from "@web/legacy/js/core/time";
|
||||
import { deserializeDateTime, formatDateTime } from "@web/core/l10n/dates";
|
||||
import { localization } from "@web/core/l10n/localization";
|
||||
|
||||
patch(ActivityMenu.prototype, "calendar", {
|
||||
async fetchSystrayActivities() {
|
||||
@@ -12,11 +12,8 @@ patch(ActivityMenu.prototype, "calendar", {
|
||||
if (group.type === "meeting") {
|
||||
for (const meeting of group.meetings) {
|
||||
if (meeting.start) {
|
||||
meeting.formattedStart = moment(
|
||||
fieldUtils.parse.datetime(meeting.start, false, { isUTC: true })
|
||||
)
|
||||
.local()
|
||||
.format(time.getLangTimeFormat());
|
||||
const date = deserializeDateTime(meeting.start);
|
||||
meeting.formattedStart = formatDateTime(date, { format: localization.timeFormat });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { datetime_to_str } from "@web/legacy/js/core/time";
|
||||
import { assignDefined } from "@mail/utils/common/misc";
|
||||
import { formatDate } from "@web/core/l10n/dates";
|
||||
import { Command } from "@mail/../tests/helpers/command";
|
||||
const { DateTime } = luxon;
|
||||
|
||||
patch(MockServer.prototype, "mail/models/discuss_channel", {
|
||||
async _performRPC(route, args) {
|
||||
@@ -953,7 +954,7 @@ patch(MockServer.prototype, "mail/models/discuss_channel", {
|
||||
*/
|
||||
_mockDiscussChannelWriteImage128(id) {
|
||||
this.pyEnv["discuss.channel"].write([id], {
|
||||
avatarCacheKey: moment.utc().format("YYYYMMDDHHmmss"),
|
||||
avatarCacheKey: DateTime.utc().toFormat("yyyyMMddHHmmss"),
|
||||
});
|
||||
const channel = this.pyEnv["discuss.channel"].searchRead([["id", "=", id]])[0];
|
||||
this.pyEnv["bus.bus"]._sendone(channel, "mail.record/insert", {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { sortBy } from "@web/core/utils/arrays";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { MockServer } from "@web/../tests/helpers/mock_server";
|
||||
import { serializeDate } from "@web/core/l10n/dates";
|
||||
import { serializeDate, deserializeDate } from "@web/core/l10n/dates";
|
||||
|
||||
const { DateTime} = luxon;
|
||||
|
||||
@@ -140,7 +140,7 @@ patch(MockServer.prototype, "mail/models/mail_activity", {
|
||||
group.activity_type_id = group.activity_type_id[0];
|
||||
let minDate;
|
||||
activites.forEach(function (activity) {
|
||||
if (!minDate || moment(activity.date_deadline) < moment(minDate)) {
|
||||
if (!minDate || deserializeDate(activity.date_deadline) < deserializeDate(minDate)) {
|
||||
minDate = activity.date_deadline;
|
||||
}
|
||||
});
|
||||
@@ -149,7 +149,7 @@ patch(MockServer.prototype, "mail/models/mail_activity", {
|
||||
let state;
|
||||
if (group.date_deadline === serializeDate(DateTime.now())) {
|
||||
state = "today";
|
||||
} else if (moment(group.date_deadline) > moment()) {
|
||||
} else if (deserializeDate(group.date_deadline) > DateTime.now()) {
|
||||
state = "planned";
|
||||
} else {
|
||||
state = "overdue";
|
||||
@@ -183,7 +183,7 @@ patch(MockServer.prototype, "mail/models/mail_activity", {
|
||||
}),
|
||||
activity_res_ids: sortBy(
|
||||
records.map((x) => x.id),
|
||||
(id) => moment(resIdToDeadline[id])
|
||||
(id) => deserializeDate(resIdToDeadline[id])
|
||||
),
|
||||
grouped_activities: groupedActivities,
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Order } from "@point_of_sale/app/store/models";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { deserializeDateTime } from "@web/core/l10n/dates";
|
||||
import { deserializeDateTime, deserializeDate } from "@web/core/l10n/dates";
|
||||
import { parseFloat } from "@web/views/fields/parsers";
|
||||
import { _lt } from "@web/core/l10n/translation";
|
||||
|
||||
@@ -333,7 +333,7 @@ export class TicketScreen extends Component {
|
||||
return this._getOrderList().filter(predicate);
|
||||
}
|
||||
getDate(order) {
|
||||
return moment(order.validation_date).format("YYYY-MM-DD hh:mm A");
|
||||
return deserializeDate(order.validation_date).toFormat("yyyy-MM-dd HH:mm a");
|
||||
}
|
||||
getTotal(order) {
|
||||
return this.env.utils.formatCurrency(order.get_total_with_tax());
|
||||
@@ -580,7 +580,7 @@ export class TicketScreen extends Component {
|
||||
modelField: "pos_reference",
|
||||
},
|
||||
DATE: {
|
||||
repr: (order) => moment(order.creation_date).format("YYYY-MM-DD hh:mm A"),
|
||||
repr: (order) => deserializeDate(order.creation_date).toFormat("yyyy-MM-dd HH:mm a"),
|
||||
displayName: this.env._t("Date"),
|
||||
modelField: "date_order",
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ import { formatFloat } from "@web/views/fields/formatters";
|
||||
import { uuidv4 } from "@point_of_sale/utils";
|
||||
// FIXME POSREF - unify use of native parseFloat and web's parseFloat. We probably don't need the native version.
|
||||
import { parseFloat as oParseFloat } from "@web/views/fields/parsers";
|
||||
import { formatDate, formatDateTime, serializeDateTime } from "@web/core/l10n/dates";
|
||||
import { formatDate, formatDateTime, serializeDateTime, deserializeDate } from "@web/core/l10n/dates";
|
||||
import {
|
||||
roundDecimals as round_di,
|
||||
roundPrecision as round_pr,
|
||||
@@ -227,8 +227,8 @@ export class Product extends PosModel {
|
||||
const categories = this.parent_category_ids.concat(this.categ.id);
|
||||
return (
|
||||
(!item.categ_id || categories.includes(item.categ_id[0])) &&
|
||||
(!item.date_start || moment.utc(item.date_start).isSameOrBefore(date)) &&
|
||||
(!item.date_end || moment.utc(item.date_end).isSameOrAfter(date))
|
||||
(!item.date_start || deserializeDate(item.date_start) <= date) &&
|
||||
(!item.date_end || deserializeDate(item.date_end) >= date)
|
||||
);
|
||||
}
|
||||
// Port of _get_product_price on product.pricelist.
|
||||
@@ -242,7 +242,7 @@ export class Product extends PosModel {
|
||||
// and were automatically sorted based on their _order by the
|
||||
// ORM. After that they are added in this order to the pricelists.
|
||||
get_price(pricelist, quantity, price_extra = 0, recurring = false) {
|
||||
var date = moment();
|
||||
const date = DateTime.now();
|
||||
|
||||
// In case of nested pricelists, it is necessary that all pricelists are made available in
|
||||
// the POS. Display a basic alert to the user in the case where there is a pricelist item
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
/** @odoo-module */
|
||||
import { Component, useState } from "@odoo/owl";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { deserializeDateTime } from "@web/core/l10n/dates";
|
||||
|
||||
/**
|
||||
* @props {models.Order} order
|
||||
@@ -29,7 +30,7 @@ export class SaleOrderRow extends Component {
|
||||
return this.order.name;
|
||||
}
|
||||
get date() {
|
||||
return moment(this.order.date_order).format("YYYY-MM-DD hh:mm A");
|
||||
return deserializeDateTime(this.order.date_order).toFormat("yyyy-MM-dd HH:mm a");
|
||||
}
|
||||
get partner() {
|
||||
const partner = this.order.partner_id;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import time from '@web/legacy/js/core/time';
|
||||
import publicWidget from '@web/legacy/js/public/public_widget';
|
||||
import { parseDate } from '@web/core/l10n/dates';
|
||||
|
||||
publicWidget.registry.ProjectRatingImage = publicWidget.Widget.extend({
|
||||
selector: '.o_portal_project_rating .o_rating_image',
|
||||
@@ -18,8 +18,8 @@ publicWidget.registry.ProjectRatingImage = publicWidget.Widget.extend({
|
||||
var $elem = $(this);
|
||||
var id = $elem.data('id');
|
||||
var ratingDate = $elem.data('rating-date');
|
||||
var baseDate = time.auto_str_to_date(ratingDate);
|
||||
var duration = moment(baseDate).fromNow();
|
||||
var baseDate = parseDate(ratingDate);
|
||||
var duration = baseDate.toRelative();
|
||||
var $rating = $('#rating_' + id);
|
||||
$rating.find('.rating_timeduration').text(duration);
|
||||
return $rating.html();
|
||||
|
||||
@@ -89,7 +89,7 @@ QUnit.module("test_mail", {}, function () {
|
||||
});
|
||||
|
||||
var activityDateFormat = function (date) {
|
||||
return date.toLocaleDateString(moment().locale(), { day: "numeric", month: "short" });
|
||||
return DateTime.now().toLocaleString({ day: "numeric", month: "short" });
|
||||
};
|
||||
|
||||
QUnit.test("activity view: simple activity rendering", async function (assert) {
|
||||
|
||||
@@ -297,6 +297,7 @@ export function formatDateTime(value, options = {}) {
|
||||
/**
|
||||
* Formats the given DateTime to the server date format.
|
||||
* @param {DateTime} value
|
||||
* @returns {string}
|
||||
*/
|
||||
export function serializeDate(value) {
|
||||
if (!dateCache.has(value)) {
|
||||
@@ -308,6 +309,7 @@ export function serializeDate(value) {
|
||||
/**
|
||||
* Formats the given DateTime to the server datetime format.
|
||||
* @param {DateTime} value
|
||||
* @returns {string}
|
||||
*/
|
||||
export function serializeDateTime(value) {
|
||||
if (!dateTimeCache.has(value)) {
|
||||
|
||||
@@ -49,6 +49,7 @@ var _t = core._t;
|
||||
const _lt = core._lt;
|
||||
const preserveCursor = OdooEditorLib.preserveCursor;
|
||||
const descendants = OdooEditorLib.descendants;
|
||||
const { DateTime } = luxon;
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} el
|
||||
@@ -1849,7 +1850,7 @@ const DatetimePickerUserValueWidget = InputUserValueWidget.extend({
|
||||
*/
|
||||
init: function () {
|
||||
this._super(...arguments);
|
||||
this._value = moment().unix().toString();
|
||||
this._value = DateTime.now().toUnixInteger().toString();
|
||||
this.__libInput = 0;
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,8 @@ import { sprintf } from "@web/core/utils/strings";
|
||||
import {_t} from "@web/legacy/js/services/core";
|
||||
import publicWidget from "@web/legacy/js/public/public_widget";
|
||||
import time from "@web/legacy/js/core/time";
|
||||
import { parseDate, formatDate } from "@web/core/l10n/dates";
|
||||
const { DateTime } = luxon;
|
||||
|
||||
publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
selector: '#wrapwrap:has(.interested_partner_assign_form, .desinterested_partner_assign_form, .opp-stage-button, .new_opp_form)',
|
||||
@@ -252,9 +254,10 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
$('.edit_opp_form .activity_summary').val($selected.attr('activity_summary'));
|
||||
}
|
||||
if ($selected.attr('delay_count')) {
|
||||
var now = moment();
|
||||
var date = now.add(parseInt($selected.attr('delay_count')), $selected.attr('delay_unit'));
|
||||
$('.edit_opp_form .activity_date_deadline').val(date.format(time.getLangDateFormat()));
|
||||
const value = +$selected.attr('delay_count');
|
||||
const unit = $selected.attr('delay_unit');
|
||||
const date = DateTime.now().plus({ [unit]: value});
|
||||
$('.edit_opp_form .activity_date_deadline').val( formatDate(date) );
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -277,9 +280,9 @@ publicWidget.registry.crmPartnerAssign = publicWidget.Widget.extend({
|
||||
|
||||
_parse_date: function (value) {
|
||||
console.log(value);
|
||||
var date = moment(value, time.getLangDateFormat(), true);
|
||||
if (date.isValid() && date.year() >= 1900) {
|
||||
return time.date_to_str(date.toDate());
|
||||
var date = parseDate(value);
|
||||
if (date.isValid && date.year >= 1900) {
|
||||
return formatDate(date);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user