From 5714260af461d7dba1f177117ad98c9ce83951c1 Mon Sep 17 00:00:00 2001 From: Shreya Date: Wed, 21 Mar 2018 19:27:15 +0530 Subject: [PATCH] replaced status with completed checkbox --- .../projects/doctype/timesheet/timesheet.js | 216 ++---------------- .../timesheet_detail/timesheet_detail.json | 135 +++-------- 2 files changed, 62 insertions(+), 289 deletions(-) diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js index a176112dea..94dd35d2d9 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.js +++ b/erpnext/projects/doctype/timesheet/timesheet.js @@ -3,6 +3,7 @@ frappe.ui.form.on("Timesheet", { setup: function(frm) { + frappe.require("/assets/erpnext/js/projects/timer.js"); frm.add_fetch('employee', 'employee_name', 'employee_name'); frm.fields_dict.employee.get_query = function() { return { @@ -50,57 +51,42 @@ frappe.ui.form.on("Timesheet", { } } - $.each(frm.doc.time_logs || [], function(i, row) { - if(row.from_time && row.status != 'Completed') { - if (frappe.datetime.now_datetime < row.from_time) { - row.status = 'Not Started'; + 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}.`)); + } } - else if (row.to_time && frappe.datetime.now_datetime > row.to_time) { - row.status = 'Overdue'; - frappe.utils.play_sound("alert"); - frappe.msgprint(__(`Timer exceeded the given hours for activity ${row.activity_type} in row ${row.idx}.`)); + frm.refresh_fields(); + }); + + let button; + $.each(frm.doc.time_logs || [], function(i, row) { + if (row.from_time <= frappe.datetime.now_datetime() && row.completed == 0) { + button = 'Resume Timer'; } else { - row.status = 'Pending'; + button = 'Start Timer'; } - } - frm.refresh_fields(); - }); - - if (frm.doc.docstatus < 2) { - - frm.add_custom_button(__('Start Timer'), function() { + }) + frm.add_custom_button(__(button), function() { var flag = true; var disabled = 1; - // Fetch the row for timer where status = Pending i.e in progress + // 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) { - if(flag && (row.status == 'Pending' || row.status == 'Overdue')) { - if (row.timer_timestamp) { - let timestamp = moment(frappe.datetime.now_datetime()).diff(moment(row.timer_timestamp),"seconds"); - timer(frm, disabled, row, timestamp); - - } - else { - row.timer_timestamp = frappe.datetime.now_datetime(); - timer(frm, disabled, row); - } + if (flag && row.from_time <= frappe.datetime.now_datetime() && row.completed == 0) { + let timestamp = moment(frappe.datetime.now_datetime()).diff(moment(row.from_time),"seconds"); + erpnext.timesheet.timer(frm, disabled, row, timestamp); flag = false; } }) - // Fetch the row for timer where status = Not Started - if (flag) { - $.each(frm.doc.time_logs || [], function(i, row) { - if(row.status == 'Not Started') { - row.timer_timestamp = frappe.datetime.now_datetime(); - timer(frm, disabled, row, timestamp); - flag = false; - } - }) - } - // If no activities found to start a timer + // If no activities found to start a timer, create new if (flag) { disabled = 0; - timer(frm,disabled); + erpnext.timesheet.timer(frm, disabled); } }).addClass("btn-primary"); } @@ -219,158 +205,6 @@ frappe.ui.form.on("Timesheet Detail", { } }); -// Spawn dialog for timer when clicked on 'Start RTimer' button -var timer = function(frm, disabled, row, timestamp=0) { - let dialog = new frappe.ui.Dialog({ - title: __("Timer"), - fields: - [ - {"fieldtype": "Link", "label": __("Activity Type"), "fieldname": "activity_type", - "reqd": 1, "options": "Activity Type", "read_only": disabled}, - {"fieldtype": "Float", "label": __("Hrs"), "fieldname": "hours", "read_only": disabled}, - {"fieldtype": "Link", "label": __("Project"), "fieldname": "project", "read_only": disabled, - "options": "Project"} - ] - - }); - if (row) { - dialog.set_values({ - 'activity_type': row.activity_type, - 'project': row.project, - 'hours': row.hours - }); - } - dialog.wrapper.append(frappe.render_template("timesheet")); - control_timer(frm, dialog, row, timestamp); - dialog.show(); -} - -var control_timer = function(frm, dialog, row, timestamp=0) { - var interval = null; - var currentIncrement = timestamp - var isPaused = false; - var initialised = row ? true : false; - var clicked = false; - var paused_time = 0; - // If row with status = Pending/ Not Completed found, initialize timer on click of 'Start Timer' - if (row) { - initialised = true; - $(".playpause span").removeClass(); - $(".playpause span").addClass("pause"); - initialiseTimer(); - } - - $(".playpause").click(function(e) { - if (!initialised) { - var args = dialog.get_values(); - if(!args) return; - if (!frm.doc.time_logs[0].activity_type) { - frm.doc.time_logs = []; - } - row = frappe.model.add_child(frm.doc, "Timesheet Detail", "time_logs"); - row.activity_type = args.activity_type; - row.from_time = frappe.datetime.get_datetime_as_string(); - row.hours = args.hours; - row.project = args.project; - row.timer_timestamp = frappe.datetime.now_datetime(); - let d = moment(row.from_time) - if(row.hours) { - d.add(row.hours, "hours"); - row.to_time = d.format(moment.defaultDatetimeFormat); - } - row.status = 'Pending'; - frm.refresh_field("time_logs"); - } - if (clicked) { - e.preventDefault(); - return false; - } - - if (!initialised) { - initialised = true; - isPaused = false; - $(".playpause span").removeClass(); - $(".playpause span").addClass("pause"); - initialiseTimer(); - } - else { - $(".playpause span").removeClass(); - if (isPaused) { - isPaused = false; - $(".playpause span").addClass("pause"); - } - else { - isPaused = true; - $(".playpause span").addClass("play"); - paused_time = currentIncrement; - } - } - }); - - // $(".stop").click(function() { - // reset(); - // }); - - // Stop the timer and save the time logged by the timer on click of 'Complete' button - dialog.set_primary_action(__("Complete"), function() { - var grid_row = cur_frm.fields_dict['time_logs'].grid.grid_rows_by_docname[row.name]; - grid_row.doc.status = "Completed"; - grid_row.doc.actual_end_time = frappe.datetime.now_datetime(); - grid_row.refresh(); - // Save the form - frm.save(); - // frm.set_value(row.timer_timestamp, currentIncrement); - reset(); - dialog.hide(); - }) - function initialiseTimer() { - interval = setInterval(function() { - if (isPaused) return; - var current = setCurrentIncrement(); - updateStopwatch(current); - }, 1000); - } - - function updateStopwatch(increment) { - var hours = Math.floor(increment / 3600); - var minutes = Math.floor((increment - (hours * 3600)) / 60); - var seconds = increment - (hours * 3600) - (minutes * 60); - - // If modal is closed by clicking outside anywhere the modal, reset the timer - if (!$('.modal-dialog').is(':visible')) { - reset(); - } - if(hours > 99) - reset(); - if(cur_dialog && cur_dialog.get_value('hours') == hours) { - isPaused = true; - initialised = false; - frappe.utils.play_sound("alert"); - frappe.msgprint(__("Timer exceeded the given hours")); - } - $(".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()); - } - - function setCurrentIncrement() { - currentIncrement += 1; - return currentIncrement; - } - - function reset() { - currentIncrement = 0; - isPaused = true; - initialised = false; - clearInterval(interval); - $(".hours").text("00"); - $(".minutes").text("00"); - $(".seconds").text("00"); - $(".playpause span").removeClass(); - $(".playpause span").addClass("play"); - } -} - var calculate_end_time = function(frm, cdt, cdn) { let child = locals[cdt][cdn]; diff --git a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json index b731dcf17f..b9482384a8 100644 --- a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json +++ b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json @@ -103,6 +103,37 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "expected_hours", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Expected Hrs", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -170,8 +201,9 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "status", - "fieldtype": "Select", + "default": "0", + "fieldname": "completed", + "fieldtype": "Check", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -179,10 +211,10 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Status", + "label": "Completed", "length": 0, "no_copy": 0, - "options": "Not Started\nPending\nCompleted\nOverdue", + "options": "", "permlevel": 0, "precision": "", "print_hide": 0, @@ -386,99 +418,6 @@ "translatable": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "timer_details", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Timer Details", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "timer_timestamp", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Timer Timestamp", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "actual_end_time", - "fieldtype": "Datetime", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Actual End Time", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -993,7 +932,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-03-21 02:09:24.262360", + "modified": "2018-03-21 17:13:32.561550", "modified_by": "Administrator", "module": "Projects", "name": "Timesheet Detail",