Timer fixes (#13443)

* alert for exceeded time only when dialog is open

* fetch row having an activity without from_time

* fixes if timesheet created from work order

* reset timer limit exceeded
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 678c016..f719ad8 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -53,16 +53,6 @@
 
 		if (frm.doc.docstatus < 1) {
 
-			$.each(frm.doc.time_logs || [], function(i, row) {
-				if(row.from_time  && !row.completed) {
-					if (row.to_time && frappe.datetime.now_datetime() > row.to_time) {
-						frappe.utils.play_sound("alert");
-						frappe.msgprint(__(`Timer exceeded the expected hours for activity ${row.activity_type} in row ${row.idx}.`));
-					}
-				}
-				frm.refresh_fields();
-			});
-
 			let button = 'Start Timer';
 			$.each(frm.doc.time_logs || [], function(i, row) {
 				if ((row.from_time <= frappe.datetime.now_datetime()) && !row.completed) {
@@ -72,8 +62,16 @@
 
 			frm.add_custom_button(__(button), function() {
 				var flag = true;
-				// Fetch the row for timer where activity is not completed and from_time is not <= now_time
 				$.each(frm.doc.time_logs || [], function(i, row) {
+					// Fetch the row for which from_time is not present
+					if (flag && row.activity_type && !row.from_time){
+						erpnext.timesheet.timer(frm, row);
+						row.from_time = frappe.datetime.now_datetime();
+						frm.refresh_fields("time_logs");
+						frm.save();
+						flag = false;
+					}
+					// Fetch the row for timer where activity is not completed and from_time is before now_time
 					if (flag && row.from_time <= frappe.datetime.now_datetime() && !row.completed) {
 						let timestamp = moment(frappe.datetime.now_datetime()).diff(moment(row.from_time),"seconds");
 						erpnext.timesheet.timer(frm, row, timestamp);
diff --git a/erpnext/public/js/projects/timer.js b/erpnext/public/js/projects/timer.js
index 925398d..0a737a6 100644
--- a/erpnext/public/js/projects/timer.js
+++ b/erpnext/public/js/projects/timer.js
@@ -50,7 +50,7 @@
 	var currentIncrement = timestamp;
 	var initialised = row ? true : false;
 	var clicked = false;
-
+	var flag = true; // Alert only once
 	// If row with not completed status, initialize timer with the time elapsed on click of 'Start Timer'.
 	if (row) {
 		initialised = true;
@@ -66,7 +66,7 @@
 			// New activity if no activities found
 			var args = dialog.get_values();
 			if(!args) return;
-			if (!frm.doc.time_logs[0].activity_type) {
+			if (frm.doc.time_logs.length <= 1 && !frm.doc.time_logs[0].activity_type && !frm.doc.time_logs[0].from_time) {
 				frm.doc.time_logs = [];
 			}
 			row = frappe.model.add_child(frm.doc, "Timesheet Detail", "time_logs");
@@ -130,8 +130,15 @@
 		if (!$('.modal-dialog').is(':visible')) {
 			reset();
 		}
-		if(hours > 99)
+		if(hours > 99999)
 			reset();
+		if(cur_dialog && cur_dialog.get_value('expected_hours') > 0) {
+			if(flag && (currentIncrement >= (cur_dialog.get_value('expected_hours') * 3600))) {
+				frappe.utils.play_sound("alert");
+				frappe.msgprint(__("Timer exceeded the given hours."));
+				flag = false;
+			}
+		}
 		$(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
 		$(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
 		$(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());