From faefcd12b9c5d6be143df9d6cb5b2fc43a359f9e Mon Sep 17 00:00:00 2001 From: Ponnusamy <95607086+Ponnusamy1-V@users.noreply.github.com> Date: Fri, 11 Oct 2024 14:08:24 +0530 Subject: [PATCH] feat: in filed date & time calculations; eg `2024-12-01 + 5d` (#27534) * feat: add and subtract datetime * fix: time picker doesn't show correct value * style: pre-commit * Revert "fix: time picker doesn't show correct value" This reverts commit e0650d11252462cba4a9296aa9a4ea8f256c503a. --- frappe/public/js/frappe/form/controls/date.js | 74 ++++++++++++++++++- .../js/frappe/form/controls/datetime.js | 2 +- frappe/public/js/frappe/form/controls/time.js | 2 +- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/form/controls/date.js b/frappe/public/js/frappe/form/controls/date.js index 0c89407ea6..2d4515a1ee 100644 --- a/frappe/public/js/frappe/form/controls/date.js +++ b/frappe/public/js/frappe/form/controls/date.js @@ -142,12 +142,84 @@ frappe.ui.form.ControlDate = class ControlDate extends frappe.ui.form.ControlDat } }); } + + eval_expression(value, type) { + if (!value || !type) { + return value; + } + const parsed_components = value.match(/[\+\-]\s*\d*\.?\d+\s*[a-zA-Z]/g); + + let system_fmt; + switch (type) { + case "date": + system_fmt = "YYYY-MM-DD"; + value = frappe.datetime.user_to_str(value, false); + break; + + case "time": + system_fmt = "HH:mm:ss"; + value = frappe.datetime.user_to_str(value, true); + break; + + case "datetime": + system_fmt = "YYYY-MM-DD HH:mm:ss"; + value = frappe.datetime.user_to_str(value, false); + break; + } + + if (!parsed_components) { + return value; + } + + let time_to_add = {}; + parsed_components.forEach((component) => { + let operator = component.match(/[\+\-]/)[0]; + let number = flt(component.match(/\d*\.?\d+/)[0]); + let unit = component.match(/[a-zA-Z]+/)[0]; + let period; + + if (operator === "-") { + number = -number; + } + + if (["datetime", "date"].includes(type)) { + if (unit.toLowerCase() === "d") { + period = "days"; + } else if (unit === "M") { + period = "months"; + } else if (unit.toLowerCase() === "y") { + period = "years"; + } + } + + if (["datetime", "time"].includes(type)) { + if (unit.toLowerCase() === "h") { + period = "hours"; + } else if (unit === "m") { + period = "minutes"; + } else if (unit.toLowerCase() === "s") { + period = "seconds"; + } + } + + if (period) { + time_to_add[period] = (time_to_add[period] || 0) + number; + } + }); + + if (Object.keys(time_to_add).length) { + value = moment(value, system_fmt).add(time_to_add).format(system_fmt); + } + + return value; + } + parse(value) { if (value) { if (value == "Invalid date") { return ""; } - return frappe.datetime.user_to_str(value, false, true); + return this.eval_expression(value, "date"); } } format_for_input(value) { diff --git a/frappe/public/js/frappe/form/controls/datetime.js b/frappe/public/js/frappe/form/controls/datetime.js index 96f2f885d2..4762b85b8d 100644 --- a/frappe/public/js/frappe/form/controls/datetime.js +++ b/frappe/public/js/frappe/form/controls/datetime.js @@ -37,7 +37,7 @@ frappe.ui.form.ControlDatetime = class ControlDatetime extends frappe.ui.form.Co } parse(value) { if (value) { - value = frappe.datetime.user_to_str(value, false); + value = this.eval_expression(value, "datetime"); if (!frappe.datetime.is_system_time_zone()) { value = frappe.datetime.convert_to_system_tz(value, true); diff --git a/frappe/public/js/frappe/form/controls/time.js b/frappe/public/js/frappe/form/controls/time.js index d7a08d4776..4125facb3b 100644 --- a/frappe/public/js/frappe/form/controls/time.js +++ b/frappe/public/js/frappe/form/controls/time.js @@ -107,7 +107,7 @@ frappe.ui.form.ControlTime = class ControlTime extends frappe.ui.form.ControlDat if (value == "Invalid date") { value = ""; } - return frappe.datetime.user_to_str(value, true); + return this.eval_expression(value, "time"); } } format_for_input(value) {