@@ -17,10 +17,11 @@ | |||||
"date_and_number_format", | "date_and_number_format", | ||||
"date_format", | "date_format", | ||||
"time_format", | "time_format", | ||||
"column_break_7", | |||||
"number_format", | "number_format", | ||||
"column_break_7", | |||||
"float_precision", | "float_precision", | ||||
"currency_precision", | "currency_precision", | ||||
"week_starts_on", | |||||
"sec_backup_limit", | "sec_backup_limit", | ||||
"backup_limit", | "backup_limit", | ||||
"encrypt_backup", | "encrypt_backup", | ||||
@@ -477,12 +478,19 @@ | |||||
"fieldname": "disable_system_update_notification", | "fieldname": "disable_system_update_notification", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"label": "Disable System Update Notification" | "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", | "icon": "fa fa-cog", | ||||
"issingle": 1, | "issingle": 1, | ||||
"links": [], | "links": [], | ||||
"modified": "2021-11-29 18:09:53.601629", | |||||
"modified": "2022-01-04 11:28:34.881192", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "System Settings", | "name": "System Settings", | ||||
@@ -499,5 +507,6 @@ | |||||
"quick_entry": 1, | "quick_entry": 1, | ||||
"sort_field": "modified", | "sort_field": "modified", | ||||
"sort_order": "ASC", | "sort_order": "ASC", | ||||
"states": [], | |||||
"track_changes": 1 | "track_changes": 1 | ||||
} | } |
@@ -100,5 +100,9 @@ frappe.ui.form.on('System Console', { | |||||
</tr></thead> | </tr></thead> | ||||
<tbody>${rows}</thead>`); | <tbody>${rows}</thead>`); | ||||
}); | }); | ||||
}, | |||||
week_starts_on() { | |||||
frappe.app.setup_moment() | |||||
} | } | ||||
}); | }); |
@@ -275,11 +275,7 @@ frappe.Application = class Application { | |||||
this.set_globals(); | this.set_globals(); | ||||
this.sync_pages(); | this.sync_pages(); | ||||
frappe.router.setup(); | 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) { | if(frappe.boot.print_css) { | ||||
frappe.dom.set_style(frappe.boot.print_css, "print-style"); | 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) { | frappe.get_module = function(m, default_module) { | ||||
@@ -254,6 +254,11 @@ $.extend(frappe.datetime, { | |||||
], true).isValid(); | ], 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 | // Proxy for dateutil and get_today | ||||
@@ -11,11 +11,26 @@ from code import compile_command | |||||
from urllib.parse import quote, urljoin | from urllib.parse import quote, urljoin | ||||
from frappe.desk.utils import slug | from frappe.desk.utils import slug | ||||
from click import secho | from click import secho | ||||
from enum import Enum | |||||
DATE_FORMAT = "%Y-%m-%d" | DATE_FORMAT = "%Y-%m-%d" | ||||
TIME_FORMAT = "%H:%M:%S.%f" | TIME_FORMAT = "%H:%M:%S.%f" | ||||
DATETIME_FORMAT = DATE_FORMAT + " " + TIME_FORMAT | 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): | def is_invalid_date_string(date_string): | ||||
# dateutil parser does not agree with dates like "0001-01-01" or "0000-00-00" | # 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): | def get_first_day_of_week(dt, as_str=False): | ||||
dt = getdate(dt) | 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 | 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): | def get_year_start(dt, as_str=False): | ||||
dt = getdate(dt) | dt = getdate(dt) | ||||
date = datetime.date(dt.year, 1, 1) | date = datetime.date(dt.year, 1, 1) | ||||