diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index 3e04643256..0af8f2e4be 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -17,10 +17,11 @@ "date_and_number_format", "date_format", "time_format", - "column_break_7", "number_format", + "column_break_7", "float_precision", "currency_precision", + "week_starts_on", "sec_backup_limit", "backup_limit", "encrypt_backup", @@ -477,12 +478,19 @@ "fieldname": "disable_system_update_notification", "fieldtype": "Check", "label": "Disable System Update Notification" + }, + { + "default": "Sunday", + "fieldname": "week_starts_on", + "fieldtype": "Select", + "label": "Week Starts On", + "options": "Sunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday" } ], "icon": "fa fa-cog", "issingle": 1, "links": [], - "modified": "2021-11-29 18:09:53.601629", + "modified": "2022-01-04 11:28:34.881192", "modified_by": "Administrator", "module": "Core", "name": "System Settings", @@ -499,5 +507,6 @@ "quick_entry": 1, "sort_field": "modified", "sort_order": "ASC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/frappe/desk/doctype/system_console/system_console.js b/frappe/desk/doctype/system_console/system_console.js index 0fe3932671..06f04e8b32 100644 --- a/frappe/desk/doctype/system_console/system_console.js +++ b/frappe/desk/doctype/system_console/system_console.js @@ -100,5 +100,9 @@ frappe.ui.form.on('System Console', { ${rows}`); }); + }, + + week_starts_on() { + frappe.app.setup_moment() } }); diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 64767e1232..f9a9931c4c 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -275,11 +275,7 @@ frappe.Application = class Application { this.set_globals(); this.sync_pages(); frappe.router.setup(); - moment.locale("en"); - moment.user_utc_offset = moment().utcOffset(); - if(frappe.boot.timezone_info) { - moment.tz.add(frappe.boot.timezone_info); - } + this.setup_moment(); if(frappe.boot.print_css) { frappe.dom.set_style(frappe.boot.print_css, "print-style"); } @@ -628,6 +624,19 @@ frappe.Application = class Application { } }); } + + setup_moment() { + moment.updateLocale('en', { + week : { + dow : frappe.datetime.get_week_starts_on_index(), + } + }); + moment.locale("en"); + moment.user_utc_offset = moment().utcOffset(); + if(frappe.boot.timezone_info) { + moment.tz.add(frappe.boot.timezone_info); + } + } } frappe.get_module = function(m, default_module) { diff --git a/frappe/public/js/frappe/utils/datetime.js b/frappe/public/js/frappe/utils/datetime.js index 7bb6076b72..09e44d917d 100644 --- a/frappe/public/js/frappe/utils/datetime.js +++ b/frappe/public/js/frappe/utils/datetime.js @@ -254,6 +254,11 @@ $.extend(frappe.datetime, { ], true).isValid(); }, + get_week_starts_on_index() { + const week_starts_on = frappe.sys_defaults.week_starts_on || "Sunday"; + return moment.weekdays().indexOf(week_starts_on); + } + }); // Proxy for dateutil and get_today diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 7a65a6f18a..9f9391b1fc 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -11,11 +11,26 @@ from code import compile_command from urllib.parse import quote, urljoin from frappe.desk.utils import slug from click import secho +from enum import Enum DATE_FORMAT = "%Y-%m-%d" TIME_FORMAT = "%H:%M:%S.%f" DATETIME_FORMAT = DATE_FORMAT + " " + TIME_FORMAT +class Weekday(Enum): + Sunday = 0 + Monday = 1 + Tuesday = 2 + Wednesday = 3 + Thursday = 4 + Friday = 5 + Saturday = 6 + +def get_week_starts_on(): + return frappe.get_system_settings('week_starts_on') or "Sunday" + +def get_start_of_week_index(): + return Weekday[get_week_starts_on()].value def is_invalid_date_string(date_string): # dateutil parser does not agree with dates like "0001-01-01" or "0000-00-00" @@ -246,9 +261,22 @@ def get_quarter_start(dt, as_str=False): def get_first_day_of_week(dt, as_str=False): dt = getdate(dt) - date = dt - datetime.timedelta(days=(dt.weekday() + 1) % 7) + date = dt - datetime.timedelta(days=get_week_start_offset_days(dt)) return date.strftime(DATE_FORMAT) if as_str else date +def get_week_start_offset_days(dt): + current_day_index = get_normalized_weekday_index(dt) + start_of_week_index = get_start_of_week_index() + + if current_day_index >= start_of_week_index: + return current_day_index - start_of_week_index + else: + return 7 - (start_of_week_index - current_day_index) + +def get_normalized_weekday_index(dt): + # starts Sunday with 0 + return (dt.weekday() + 1) % 7 + def get_year_start(dt, as_str=False): dt = getdate(dt) date = datetime.date(dt.year, 1, 1)