diff --git a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js index cdfd919778e..75985607dd2 100644 --- a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js +++ b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js @@ -44,7 +44,6 @@ export class TimeOffCalendarYearRenderer extends CalendarYearRenderer { weekNumbers: true, weekNumbersWithinDays: false, weekLabel: _t("Week"), - firstDay: 0, }); } diff --git a/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js b/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js index 8e89fdd201c..aced367c18f 100644 --- a/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js +++ b/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js @@ -9,6 +9,7 @@ import { getColor } from "../colors"; import { useCalendarPopover, useClickHandler, useFullCalendar } from "../hooks"; import { CalendarCommonPopover } from "./calendar_common_popover"; import { browser } from "@web/core/browser/browser"; +import { getWeekNumber } from "../utils"; import { Component, onMounted, useEffect } from "@odoo/owl"; @@ -112,7 +113,7 @@ export class CalendarCommonRenderer extends Component { unselectAuto: false, weekLabel: this.props.model.scale === "month" && this.env.isSmall ? "" : _t("Week"), weekends: this.props.isWeekendVisible, - weekNumberCalculation: "ISO", + weekNumberCalculation: (date) => getWeekNumber(date, this.props.model.firstDayOfWeek), weekNumbers: true, weekNumbersWithinDays: !this.env.isSmall, windowResize: this.onWindowResizeDebounced, diff --git a/addons/web/static/src/views/calendar/calendar_controller.js b/addons/web/static/src/views/calendar/calendar_controller.js index fc14fdc0f38..107b291fcbe 100644 --- a/addons/web/static/src/views/calendar/calendar_controller.js +++ b/addons/web/static/src/views/calendar/calendar_controller.js @@ -19,6 +19,7 @@ import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler"; import { ViewScaleSelector } from "@web/views/view_components/view_scale_selector"; import { CogMenu } from "@web/search/cog_menu/cog_menu"; import { browser } from "@web/core/browser/browser"; +import { getWeekNumber } from "./utils"; import { Component, useState } from "@odoo/owl"; @@ -137,7 +138,7 @@ export class CalendarController extends Component { } get currentWeek() { - return this.date.toFormat("W"); + return getWeekNumber(this.model.rangeStart); } get rendererProps() { diff --git a/addons/web/static/src/views/calendar/calendar_year/calendar_year_renderer.js b/addons/web/static/src/views/calendar/calendar_year/calendar_year_renderer.js index 7673953d6d5..7ba34717b2f 100644 --- a/addons/web/static/src/views/calendar/calendar_year/calendar_year_renderer.js +++ b/addons/web/static/src/views/calendar/calendar_year/calendar_year_renderer.js @@ -5,6 +5,7 @@ import { useDebounced } from "@web/core/utils/timing"; import { getColor } from "../colors"; import { useCalendarPopover, useFullCalendar } from "../hooks"; import { CalendarYearPopover } from "./calendar_year_popover"; +import { getWeekNumber } from "../utils"; import { Component, useEffect, useRef } from "@odoo/owl"; @@ -58,7 +59,7 @@ export class CalendarYearRenderer extends Component { timeZone: luxon.Settings.defaultZone.name, titleFormat: { month: "long", year: "numeric" }, unselectAuto: false, - weekNumberCalculation: "ISO", + weekNumberCalculation: (date) => getWeekNumber(date, this.props.model.firstDayOfWeek), weekNumbers: false, windowResize: this.onWindowResizeDebounced, }; diff --git a/addons/web/static/src/views/calendar/utils.js b/addons/web/static/src/views/calendar/utils.js index 7378ddf104b..a22b3c7a53c 100644 --- a/addons/web/static/src/views/calendar/utils.js +++ b/addons/web/static/src/views/calendar/utils.js @@ -12,3 +12,33 @@ export function getFormattedDateSpan(start, end) { : start.toFormat("DDD") + " - " + end.toFormat("DDD"); } } + +/** + * Get the week number of a given date. + * Returns the ISO week number of the Monday nearest to the first day of the week. + * + * @param {Date | luxon.DateTime} date + * @param {number} first day of the week (optional) + * @returns {number} week number + */ +export function getWeekNumber(date, firstDay) { + if (!date.isLuxonDateTime) { + date = luxon.DateTime.fromJSDate(date); + } + if (Number.isInteger(firstDay)) { // go to start of week + date = date.minus({ days: (date.weekday + 7 - firstDay) % 7 }); + } else { + firstDay = date.weekday; + } + // go to nearest Monday, up to 3 days back- or forwards + date = firstDay > 1 && firstDay < 5 // if firstDay after Mon & before Fri + ? date.minus({ days: (date.weekday + 6) % 7 }) // then go back 1-3 days + : date.plus({ days: (8 - date.weekday) % 7 }); // else go forwards 0-3 days + date = date.plus({ days: 6 }); // go to last weekday of ISO week + const jan4 = luxon.DateTime.local(date.year, 1, 4); + // count from previous year if week falls before Jan 4 + const diffDays = date < jan4 + ? date.diff(jan4.minus({ years: 1 }), 'day').days + : date.diff(jan4, 'day').days; + return Math.trunc(diffDays / 7) + 1; +} diff --git a/addons/web/static/tests/views/calendar/calendar_view_tests.js b/addons/web/static/tests/views/calendar/calendar_view_tests.js index 3076a7c764b..8534dc20385 100644 --- a/addons/web/static/tests/views/calendar/calendar_view_tests.js +++ b/addons/web/static/tests/views/calendar/calendar_view_tests.js @@ -1241,8 +1241,8 @@ QUnit.module("Views", ({ beforeEach }) => { }); QUnit.test(`week numbering`, async (assert) => { - // The week is now calculated by FullCalendar (ISO week). If it's start a sunday it - // returns the week of the monday. + // Using ISO week calculation, get the ISO week number of + // the Monday nearest to the start of the week. patchWithCleanup(localization, { weekStart: 7 }); @@ -4214,7 +4214,7 @@ QUnit.module("Views", ({ beforeEach }) => { ); assert.strictEqual( target.querySelector(".fc-head .fc-week-number").textContent, - "Week 36", + "Week 37", "The number of the week should be correct" ); });