diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.json b/erpnext/hr/doctype/salary_slip/salary_slip.json index 113a54b236..9ba4c32b1d 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.json +++ b/erpnext/hr/doctype/salary_slip/salary_slip.json @@ -288,7 +288,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -1171,7 +1171,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-07-01 12:25:38.497538", + "modified": "2016-07-06 13:45:33.521611", "modified_by": "Administrator", "module": "HR", "name": "Salary Slip", diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 571f75a61f..ee47ba4229 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -240,7 +240,7 @@ class ProductionOrder(Document): return holidays[holiday_list] - def make_time_logs(self): + def make_time_logs(self, open_new=False): """Capacity Planning. Plan time logs based on earliest availablity of workstation after Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted before manufacturing entry can be made.""" @@ -256,7 +256,7 @@ class ProductionOrder(Document): last_workstation_idx = {} for i, d in enumerate(self.operations): - if d.workstation: + if d.workstation and d.status != 'Completed': last_workstation_idx[d.workstation] = i # set last row index of workstation self.set_start_end_time_for_workstation(d, workstation_list, last_workstation_idx.get(d.workstation)) @@ -269,6 +269,7 @@ class ProductionOrder(Document): try: time_sheet.validate_time_logs() except OverlapError: + if frappe.message_log: frappe.message_log.pop() time_sheet.move_to_next_non_overlapping_slot(d.idx) from_time, to_time = self.get_start_end_time(time_sheet, d.name) @@ -280,6 +281,9 @@ class ProductionOrder(Document): d.planned_start_time = from_time d.planned_end_time = to_time d.db_update() + + if time_sheet and open_new: + return time_sheet if time_sheet: time_sheet.save() @@ -531,30 +535,7 @@ def get_default_warehouse(): @frappe.whitelist() def make_timesheet(source_name, target_doc=None): - def postprocess(source, target): - target.production_order = source.name - target.naming_series = 'TS-' - - def update_item(source, target, source_parent): - target.completed_qty = source_parent.qty - source.completed_qty - - doc = get_mapped_doc("Production Order", source_name, { - "Production Order": { - "doctype": "Time Sheet", - "validation": { - "docstatus": ["=", 1] - } - }, - "Production Order Operation": { - "doctype": "Time Sheet Detail", - "field_map": { - "name": "operation_id", - "operation": "operation", - "workstation": "workstation" - }, - "postprocess": update_item, - "condition": lambda doc: doc.status != 'Completed' - } - }, target_doc, postprocess) - - return doc + po = frappe.get_doc('Production Order', source_name) + ts = po.make_time_logs(open_new=True) + + return ts diff --git a/erpnext/projects/doctype/time_sheet/time_sheet.js b/erpnext/projects/doctype/time_sheet/time_sheet.js index a4cb3ae1a6..022da23309 100644 --- a/erpnext/projects/doctype/time_sheet/time_sheet.js +++ b/erpnext/projects/doctype/time_sheet/time_sheet.js @@ -105,20 +105,25 @@ frappe.ui.form.on("Time Sheet Detail", { activity_type: function(frm, cdt, cdn) { child = locals[cdt][cdn]; - frappe.call({ - method: "erpnext.projects.doctype.time_sheet.time_sheet.get_activity_cost", - args: { - employee: frm.doc.employee, - activity_type: child.activity_type - }, - callback: function(r){ - if(r.message){ - frappe.model.set_value(cdt, cdn, 'billing_rate', r.message['billing_rate']); - frappe.model.set_value(cdt, cdn, 'costing_rate', r.message['costing_rate']); - calculate_billing_costing_amount(frm, cdt, cdn) + if(frm.doc.employee || frm.doc.production_order){ + frappe.call({ + method: "erpnext.projects.doctype.time_sheet.time_sheet.get_activity_cost", + args: { + employee: frm.doc.employee, + activity_type: child.activity_type + }, + callback: function(r){ + if(r.message){ + frappe.model.set_value(cdt, cdn, 'billing_rate', r.message['billing_rate']); + frappe.model.set_value(cdt, cdn, 'costing_rate', r.message['costing_rate']); + calculate_billing_costing_amount(frm, cdt, cdn) + } } - } - }) + }) + }else { + frappe.model.set_value(cdt, cdn, 'activity_type', null); + frappe.show_alert(__("Select employee")) + } } }); diff --git a/erpnext/projects/doctype/time_sheet/time_sheet.py b/erpnext/projects/doctype/time_sheet/time_sheet.py index 17f0023572..12e7202771 100644 --- a/erpnext/projects/doctype/time_sheet/time_sheet.py +++ b/erpnext/projects/doctype/time_sheet/time_sheet.py @@ -89,6 +89,9 @@ class TimeSheet(Document): if self.production_order and flt(pending_qty) < flt(data.completed_qty): frappe.throw(_("Row {0}: Completed Qty cannot be more than {0} for operation {1}").format(data.idx, pending_qty, self.operation), OverProductionLoggedError) + + if data.billable and flt(data.billing_rate) == 0.0: + frappe.throw(_("Row {0}: Billing Rate must be greater than zero.").format(data.idx)) def update_production_order(self, time_sheet): if self.production_order: diff --git a/erpnext/projects/doctype/time_sheet_detail/time_sheet_detail.json b/erpnext/projects/doctype/time_sheet_detail/time_sheet_detail.json index b7bda2c34d..50bddc5c28 100644 --- a/erpnext/projects/doctype/time_sheet_detail/time_sheet_detail.json +++ b/erpnext/projects/doctype/time_sheet_detail/time_sheet_detail.json @@ -13,7 +13,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "depends_on": "", + "depends_on": "eval:parent.employee", "fieldname": "billable", "fieldtype": "Check", "hidden": 0, @@ -85,6 +85,30 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "section_break_3", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -138,189 +162,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "section_break_3", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "project", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Project", - "length": 0, - "no_copy": 0, - "options": "Project", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "project", - "fieldname": "task", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Task", - "length": 0, - "no_copy": 0, - "options": "Task", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:parent.production_order", - "fieldname": "workstation", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Workstation", - "length": 0, - "no_copy": 0, - "options": "Workstation", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:parent.production_order", - "fieldname": "operation", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Operation", - "length": 0, - "no_copy": 0, - "options": "Operation", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:parent.production_order", - "fieldname": "operation_id", - "fieldtype": "Data", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Operation Id", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "depends_on": "eval:parent.production_order", - "fieldname": "completed_qty", - "fieldtype": "Float", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Completed Qty", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "2", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, + "depends_on": "eval:parent.employee", "fieldname": "section_break_11", "fieldtype": "Section Break", "hidden": 0, @@ -470,6 +312,213 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "section_break_7", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:parent.production_order", + "fieldname": "completed_qty", + "fieldtype": "Float", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Completed Qty", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "2", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "project", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Project", + "length": 0, + "no_copy": 0, + "options": "Project", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "project", + "fieldname": "task", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Task", + "length": 0, + "no_copy": 0, + "options": "Task", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_12", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:parent.production_order", + "fieldname": "workstation", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Workstation", + "length": 0, + "no_copy": 0, + "options": "Workstation", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:parent.production_order", + "fieldname": "operation", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Operation", + "length": 0, + "no_copy": 0, + "options": "Operation", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "depends_on": "eval:parent.production_order", + "fieldname": "operation_id", + "fieldtype": "Data", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Operation Id", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "hide_heading": 0, @@ -482,7 +531,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-06-29 17:18:37.442965", + "modified": "2016-07-06 13:40:41.419370", "modified_by": "Administrator", "module": "Projects", "name": "Time Sheet Detail",