Repository: frappe/frappe
Pull request: fix: handle negative duration
Closes #14492

Problem statement:
Negative duration gets rendered wrong
## Description of the issue

When setting a negative number in a duration field, the value is displayed incorrectly.

## Context information (for bug reports)

**Output of `bench version`**
```
erpnext 13.12.1
frappe 13.11.0
```

## Steps to reproduce the issue

1. Create a DocType with a Duration field
2. Set a negative duration by code (in seconds)

    ```js
    cur_frm.set_value("duration_field", 60 * 60) // -> "1h"
    cur_frm.set_value("duration_field", -1 * 60 * 60)) // -> "-1d -1h"
    ```

### Observed result

"-1d -1h"

### Expected result

"-1h"

Hints from issue discussion:

Commit message: fix: handle negative duration

Patch to review:
diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js
index 831538d25599..065ae415f524 100644
--- a/frappe/public/js/frappe/utils/utils.js
+++ b/frappe/public/js/frappe/utils/utils.js
@@ -1049,16 +1049,16 @@ Object.assign(frappe.utils, {
 		return duration;
 	},
 
-	seconds_to_duration(value, duration_options) {
-		let secs = value;
+	seconds_to_duration(secs, duration_options) {
+		let round = secs > 0 ? Math.floor : Math.ceil;
 		let total_duration = {
-			days: Math.floor(secs / (3600 * 24)),
-			hours: Math.floor(secs % (3600 * 24) / 3600),
-			minutes: Math.floor(secs % 3600 / 60),
-			seconds: Math.floor(secs % 60)
+			days: round(secs / (3600 * 24)),
+			hours: round(secs % (3600 * 24) / 3600),
+			minutes: round(secs % 3600 / 60),
+			seconds: round(secs % 60)
 		};
 		if (duration_options.hide_days) {
-			total_duration.hours = Math.floor(secs / 3600);
+			total_duration.hours = round(secs / 3600);
 			total_duration.days = 0;
 		}
 		return total_duration;


Code review comments:
diff_hunk: @@ -1049,16 +1049,16 @@ Object.assign(frappe.utils, {
 		return duration;
 	},
 
-	seconds_to_duration(value, duration_options) {
-		let secs = value;
+	seconds_to_duration(secs, duration_options) {
path: frappe/public/js/frappe/utils/utils.js
text: @user1:
Can you make it `seconds` please?

diff_hunk: @@ -1049,16 +1049,16 @@ Object.assign(frappe.utils, {
 		return duration;
 	},
 
-	seconds_to_duration(value, duration_options) {
-		let secs = value;
+	seconds_to_duration(secs, duration_options) {
+		let round = secs > 0 ? Math.floor : Math.ceil;
path: frappe/public/js/frappe/utils/utils.js
text: @user1:
```suggestion
		const round = secs > 0 ? Math.floor : Math.ceil;
```