blob: 9dae7118d9a0672ee08cc228f41202a959864f6d [file] [log] [blame]
Shreya5bf24be2018-03-21 22:20:46 +05301frappe.provide("erpnext.timesheet");
Shreya68ec22a2018-03-21 19:25:56 +05302
Shreya8f062662018-03-21 22:20:11 +05303erpnext.timesheet.timer = function(frm, row, timestamp=0) {
Shreya68ec22a2018-03-21 19:25:56 +05304 let dialog = new frappe.ui.Dialog({
5 title: __("Timer"),
6 fields:
7 [
8 {"fieldtype": "Link", "label": __("Activity Type"), "fieldname": "activity_type",
Shreya8f062662018-03-21 22:20:11 +05309 "reqd": 1, "options": "Activity Type"},
10 {"fieldtype": "Link", "label": __("Project"), "fieldname": "project", "options": "Project"},
Shreya8bb0f052018-03-23 11:46:45 +053011 {"fieldtype": "Link", "label": __("Task"), "fieldname": "task", "options": "Task"},
Shreya68ec22a2018-03-21 19:25:56 +053012 {"fieldtype": "Float", "label": __("Expected Hrs"), "fieldname": "expected_hours"},
13 {"fieldtype": "Section Break"},
14 {"fieldtype": "HTML", "fieldname": "timer_html"}
15 ]
Shreya68ec22a2018-03-21 19:25:56 +053016 });
Shreya8f062662018-03-21 22:20:11 +053017
Shreya68ec22a2018-03-21 19:25:56 +053018 if (row) {
19 dialog.set_values({
20 'activity_type': row.activity_type,
21 'project': row.project,
Shreya8bb0f052018-03-23 11:46:45 +053022 'task': row.task,
Shreya68ec22a2018-03-21 19:25:56 +053023 'expected_hours': row.expected_hours
24 });
25 }
Shreya55901142018-03-22 11:40:38 +053026 dialog.get_field("timer_html").$wrapper.append(get_timer_html());
27 function get_timer_html() {
28 return `
29 <div class="stopwatch">
30 <span class="hours">00</span>
31 <span class="colon">:</span>
32 <span class="minutes">00</span>
33 <span class="colon">:</span>
34 <span class="seconds">00</span>
35 </div>
36 <div class="playpause text-center">
37 <button class= "btn btn-primary btn-start"> ${ __("Start") } </button>
38 <button class= "btn btn-primary btn-complete"> ${ __("Complete") } </button>
39 </div>
40 `;
Shreya822ba212018-03-22 11:56:05 +053041 }
Shreya55901142018-03-22 11:40:38 +053042 erpnext.timesheet.control_timer(frm, dialog, row, timestamp);
Shreya68ec22a2018-03-21 19:25:56 +053043 dialog.show();
Shreya5bf24be2018-03-21 22:20:46 +053044};
Shreya68ec22a2018-03-21 19:25:56 +053045
Shreya55901142018-03-22 11:40:38 +053046erpnext.timesheet.control_timer = function(frm, dialog, row, timestamp=0) {
shreyashah115@gmail.com5281fe82018-11-27 13:11:30 +053047 var $btn_start = dialog.$wrapper.find(".playpause .btn-start");
48 var $btn_complete = dialog.$wrapper.find(".playpause .btn-complete");
Shreya68ec22a2018-03-21 19:25:56 +053049 var interval = null;
Shreya5bf24be2018-03-21 22:20:46 +053050 var currentIncrement = timestamp;
Deepesh Garg64802d12022-11-20 19:45:51 +053051 var initialized = row ? true : false;
Shreya68ec22a2018-03-21 19:25:56 +053052 var clicked = false;
Shreya Shah5d716092018-04-02 10:32:39 +053053 var flag = true; // Alert only once
Shreya68ec22a2018-03-21 19:25:56 +053054 // If row with not completed status, initialize timer with the time elapsed on click of 'Start Timer'.
55 if (row) {
Deepesh Garg64802d12022-11-20 19:45:51 +053056 initialized = true;
Shreya8f062662018-03-21 22:20:11 +053057 $btn_start.hide();
58 $btn_complete.show();
Deepesh Garg64802d12022-11-20 19:45:51 +053059 initializeTimer();
Shreya68ec22a2018-03-21 19:25:56 +053060 }
Deepesh Garg64802d12022-11-20 19:45:51 +053061
62 if (!initialized) {
Shreya8f062662018-03-21 22:20:11 +053063 $btn_complete.hide();
64 }
Deepesh Garg64802d12022-11-20 19:45:51 +053065
Shreya68ec22a2018-03-21 19:25:56 +053066 $btn_start.click(function(e) {
Deepesh Garg64802d12022-11-20 19:45:51 +053067 if (!initialized) {
Shreya68ec22a2018-03-21 19:25:56 +053068 // New activity if no activities found
69 var args = dialog.get_values();
70 if(!args) return;
Shreya Shah5d716092018-04-02 10:32:39 +053071 if (frm.doc.time_logs.length <= 1 && !frm.doc.time_logs[0].activity_type && !frm.doc.time_logs[0].from_time) {
Shreya68ec22a2018-03-21 19:25:56 +053072 frm.doc.time_logs = [];
73 }
74 row = frappe.model.add_child(frm.doc, "Timesheet Detail", "time_logs");
75 row.activity_type = args.activity_type;
76 row.from_time = frappe.datetime.get_datetime_as_string();
Shreya8bb0f052018-03-23 11:46:45 +053077 row.project = args.project;
78 row.task = args.task;
Shreya68ec22a2018-03-21 19:25:56 +053079 row.expected_hours = args.expected_hours;
80 row.completed = 0;
Shreya5bf24be2018-03-21 22:20:46 +053081 let d = moment(row.from_time);
Shreya68ec22a2018-03-21 19:25:56 +053082 if(row.expected_hours) {
83 d.add(row.expected_hours, "hours");
Rushabh Mehta096b9432018-06-25 22:37:43 +053084 row.to_time = d.format(frappe.defaultDatetimeFormat);
Shreya68ec22a2018-03-21 19:25:56 +053085 }
86 frm.refresh_field("time_logs");
Shreya8f062662018-03-21 22:20:11 +053087 frm.save();
Shreya68ec22a2018-03-21 19:25:56 +053088 }
Shreya8f062662018-03-21 22:20:11 +053089
Shreya68ec22a2018-03-21 19:25:56 +053090 if (clicked) {
91 e.preventDefault();
92 return false;
93 }
94
Deepesh Garg64802d12022-11-20 19:45:51 +053095 if (!initialized) {
96 initialized = true;
Shreya8f062662018-03-21 22:20:11 +053097 $btn_start.hide();
98 $btn_complete.show();
Deepesh Garg64802d12022-11-20 19:45:51 +053099 initializeTimer();
Shreya68ec22a2018-03-21 19:25:56 +0530100 }
Shreya68ec22a2018-03-21 19:25:56 +0530101 });
102
Shreya8f062662018-03-21 22:20:11 +0530103 // Stop the timer and update the time logged by the timer on click of 'Complete' button
104 $btn_complete.click(function() {
Shreya822ba212018-03-22 11:56:05 +0530105 var grid_row = cur_frm.fields_dict['time_logs'].grid.get_row(row.idx - 1);
Shreya8f062662018-03-21 22:20:11 +0530106 var args = dialog.get_values();
Shreya68ec22a2018-03-21 19:25:56 +0530107 grid_row.doc.completed = 1;
Shreya8f062662018-03-21 22:20:11 +0530108 grid_row.doc.activity_type = args.activity_type;
109 grid_row.doc.project = args.project;
Shreya8bb0f052018-03-23 11:46:45 +0530110 grid_row.doc.task = args.task;
Shreya8f062662018-03-21 22:20:11 +0530111 grid_row.doc.expected_hours = args.expected_hours;
Shreya68ec22a2018-03-21 19:25:56 +0530112 grid_row.doc.hours = currentIncrement / 3600;
113 grid_row.doc.to_time = frappe.datetime.now_datetime();
114 grid_row.refresh();
Deepesh Garg64802d12022-11-20 19:45:51 +0530115 frm.dirty();
Shreya68ec22a2018-03-21 19:25:56 +0530116 frm.save();
117 reset();
118 dialog.hide();
Shreya5bf24be2018-03-21 22:20:46 +0530119 });
Deepesh Garg64802d12022-11-20 19:45:51 +0530120
121 function initializeTimer() {
Shreya68ec22a2018-03-21 19:25:56 +0530122 interval = setInterval(function() {
Shreya68ec22a2018-03-21 19:25:56 +0530123 var current = setCurrentIncrement();
124 updateStopwatch(current);
125 }, 1000);
126 }
127
128 function updateStopwatch(increment) {
129 var hours = Math.floor(increment / 3600);
130 var minutes = Math.floor((increment - (hours * 3600)) / 60);
131 var seconds = increment - (hours * 3600) - (minutes * 60);
132
Shreya8f062662018-03-21 22:20:11 +0530133 // If modal is closed by clicking anywhere outside, reset the timer
Shreya68ec22a2018-03-21 19:25:56 +0530134 if (!$('.modal-dialog').is(':visible')) {
135 reset();
136 }
Shreya Shah5d716092018-04-02 10:32:39 +0530137 if(hours > 99999)
Shreya5bf24be2018-03-21 22:20:46 +0530138 reset();
Shreya Shah5d716092018-04-02 10:32:39 +0530139 if(cur_dialog && cur_dialog.get_value('expected_hours') > 0) {
140 if(flag && (currentIncrement >= (cur_dialog.get_value('expected_hours') * 3600))) {
141 frappe.utils.play_sound("alert");
142 frappe.msgprint(__("Timer exceeded the given hours."));
143 flag = false;
144 }
145 }
Shreya68ec22a2018-03-21 19:25:56 +0530146 $(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
147 $(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
148 $(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
149 }
150
151 function setCurrentIncrement() {
152 currentIncrement += 1;
153 return currentIncrement;
154 }
155
156 function reset() {
157 currentIncrement = 0;
Deepesh Garg64802d12022-11-20 19:45:51 +0530158 initialized = false;
Shreya68ec22a2018-03-21 19:25:56 +0530159 clearInterval(interval);
160 $(".hours").text("00");
161 $(".minutes").text("00");
162 $(".seconds").text("00");
Shreya8f062662018-03-21 22:20:11 +0530163 $btn_complete.hide();
164 $btn_start.show();
Shreya68ec22a2018-03-21 19:25:56 +0530165 }
Ankush Menat4551d7d2021-08-19 13:41:10 +0530166};