From 80261379982e762a2b70f64b500cdcc95c666dbc Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Thu, 26 Mar 2015 19:19:11 +0530 Subject: [PATCH] employee name added to activity cost title changed for activity type time log -fetch logic added for billing and internal rate validations and calculation logic added --- .../doctype/activity_cost/activity_cost.json | 34 ++++++++++++-- .../doctype/activity_cost/activity_cost.py | 8 +++- .../doctype/project_task/project_task.json | 4 +- erpnext/projects/doctype/time_log/time_log.js | 42 ++++++++++++++++- .../projects/doctype/time_log/time_log.json | 47 +++++++++++++++++-- erpnext/projects/doctype/time_log/time_log.py | 22 +++++++++ 6 files changed, 143 insertions(+), 14 deletions(-) diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.json b/erpnext/projects/doctype/activity_cost/activity_cost.json index 48c1247ab6..0f37c5c747 100644 --- a/erpnext/projects/doctype/activity_cost/activity_cost.json +++ b/erpnext/projects/doctype/activity_cost/activity_cost.json @@ -2,6 +2,7 @@ "allow_copy": 0, "allow_import": 1, "allow_rename": 1, + "autoname": "Activity Cost - .#", "creation": "2015-03-23 02:00:21.861546", "custom": 0, "docstatus": 0, @@ -24,10 +25,18 @@ "print_hide": 0, "read_only": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0 }, + { + "fieldname": "employee_name", + "fieldtype": "Read Only", + "label": "Employee Name", + "options": "employee.employee_name", + "permlevel": 0, + "precision": "" + }, { "fieldname": "column_break_2", "fieldtype": "Column Break", @@ -50,7 +59,7 @@ "print_hide": 0, "read_only": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0 }, @@ -62,6 +71,8 @@ }, { "allow_on_submit": 0, + "default": "0", + "description": "per hour", "fieldname": "billing_rate", "fieldtype": "Currency", "hidden": 0, @@ -87,7 +98,9 @@ }, { "allow_on_submit": 0, - "fieldname": "intrernal_rate", + "default": "0", + "description": "per hour", + "fieldname": "internal_rate", "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, @@ -103,6 +116,16 @@ "reqd": 0, "search_index": 0, "set_only_once": 0 + }, + { + "fieldname": "title", + "fieldtype": "Data", + "hidden": 1, + "label": "title", + "no_copy": 1, + "permlevel": 0, + "precision": "", + "read_only": 1 } ], "hide_heading": 0, @@ -112,7 +135,7 @@ "is_submittable": 0, "issingle": 0, "istable": 0, - "modified": "2015-03-23 02:01:53.789728", + "modified": "2015-03-25 07:50:46.554655", "modified_by": "Administrator", "module": "Projects", "name": "Activity Cost", @@ -142,5 +165,6 @@ "read_only": 0, "read_only_onload": 0, "sort_field": "modified", - "sort_order": "DESC" + "sort_order": "DESC", + "title_field": "title" } \ No newline at end of file diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.py b/erpnext/projects/doctype/activity_cost/activity_cost.py index 31df89aa66..efba0f6734 100644 --- a/erpnext/projects/doctype/activity_cost/activity_cost.py +++ b/erpnext/projects/doctype/activity_cost/activity_cost.py @@ -3,8 +3,12 @@ # For license information, please see license.txt from __future__ import unicode_literals -import frappe +from frappe import _ from frappe.model.document import Document class ActivityCost(Document): - pass + def validate(self): + self.set_title() + + def set_title(self): + self.title = _("{0} for {1}").format(self.employee_name, self.activity_type) diff --git a/erpnext/projects/doctype/project_task/project_task.json b/erpnext/projects/doctype/project_task/project_task.json index c29dcc05d6..00e97f6402 100644 --- a/erpnext/projects/doctype/project_task/project_task.json +++ b/erpnext/projects/doctype/project_task/project_task.json @@ -51,7 +51,7 @@ { "fieldname": "edit_task", "fieldtype": "Button", - "label": "Edit Task", + "label": "View Task", "permlevel": 0, "precision": "" }, @@ -143,7 +143,7 @@ "is_submittable": 0, "issingle": 0, "istable": 1, - "modified": "2015-02-23 01:55:18.865117", + "modified": "2015-03-26 04:55:36.680900", "modified_by": "Administrator", "module": "Projects", "name": "Project Task", diff --git a/erpnext/projects/doctype/time_log/time_log.js b/erpnext/projects/doctype/time_log/time_log.js index a49b1f1c04..e4fbfc3ee1 100644 --- a/erpnext/projects/doctype/time_log/time_log.js +++ b/erpnext/projects/doctype/time_log/time_log.js @@ -41,4 +41,44 @@ frappe.ui.form.on("Time Log", "to_time", function(frm) { if(frm._setting_hours) return; frm.set_value("hours", moment(cur_frm.doc.to_time).diff(moment(cur_frm.doc.from_time), "hours")); -}); \ No newline at end of file + +}); + +var calculate_cost = function(doc) { + cur_frm.set_value("internal_cost", doc.internal_rate * doc.hours); + if (doc.billable==1){ + cur_frm.set_value("billing_amount", doc.billing_rate * doc.hours); + } +} + +frappe.ui.form.on("Time Log", "hours", function(frm) { + calculate_cost(frm.doc); +}); + +frappe.ui.form.on("Time Log", "activity_type", function(frm) { + return frappe.call({ + method: "erpnext.projects.doctype.time_log.time_log.get_activity_cost", + args: { + "employee": frm.doc.employee, + "activity_type": frm.doc.activity_type + }, + callback: function(r) { + if(!r.exc) { + cur_frm.set_value("internal_rate", r.message.internal_rate); + cur_frm.set_value("billing_rate", r.message.billing_rate); + calculate_cost(frm.doc); + } + } + }); +}); + +cur_frm.cscript.employee = cur_frm.cscript.activity_type; + +cur_frm.cscript.billable = function(doc) { + if (doc.billable==1) { + calculate_cost(doc); + } + else { + cur_frm.set_value("billing_amount", 0); + } +} diff --git a/erpnext/projects/doctype/time_log/time_log.json b/erpnext/projects/doctype/time_log/time_log.json index 217bc65960..8b7c956f36 100644 --- a/erpnext/projects/doctype/time_log/time_log.json +++ b/erpnext/projects/doctype/time_log/time_log.json @@ -35,6 +35,7 @@ "reqd": 1 }, { + "default": "0", "fieldname": "hours", "fieldtype": "Float", "in_list_view": 1, @@ -204,18 +205,30 @@ "read_only": 0 }, { - "fieldname": "billing_rate", - "fieldtype": "Currency", - "label": "Billing Rate", + "depends_on": "", + "fieldname": "section_break_24", + "fieldtype": "Section Break", "permlevel": 0, "precision": "" }, { + "default": "0", + "description": "per hour", "fieldname": "internal_rate", "fieldtype": "Currency", "label": "Internal Rate", "permlevel": 0, - "precision": "" + "precision": "", + "read_only": 1 + }, + { + "default": "0", + "fieldname": "internal_cost", + "fieldtype": "Currency", + "label": "Internal Cost", + "permlevel": 0, + "precision": "", + "read_only": 1 }, { "fieldname": "column_break_25", @@ -223,6 +236,32 @@ "permlevel": 0, "precision": "" }, + { + "default": "0", + "description": "per hour", + "fieldname": "billing_rate", + "fieldtype": "Currency", + "label": "Billing Rate", + "permlevel": 0, + "precision": "", + "read_only": 1 + }, + { + "default": "0", + "description": "will be updated only if Time Log is 'Billable'", + "fieldname": "billing_amount", + "fieldtype": "Currency", + "label": "Billing Amount", + "permlevel": 0, + "precision": "", + "read_only": 1 + }, + { + "fieldname": "section_break_29", + "fieldtype": "Section Break", + "permlevel": 0, + "precision": "" + }, { "description": "Will be updated when batched.", "fieldname": "time_log_batch", diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py index 36bf5a7f6c..de37912328 100644 --- a/erpnext/projects/doctype/time_log/time_log.py +++ b/erpnext/projects/doctype/time_log/time_log.py @@ -24,12 +24,15 @@ class TimeLog(Document): self.check_workstation_timings() self.validate_production_order() self.validate_manufacturing() + self.validate_cost() def on_submit(self): self.update_production_order() + self.update_project() def on_cancel(self): self.update_production_order() + self.update_project() def before_update_after_submit(self): self.set_status() @@ -206,6 +209,18 @@ class TimeLog(Document): self.production_order = None self.operation = None self.quantity = None + + def validate_cost(self): + self.internal_cost = self.internal_rate * self.hours + if self.billable: + self.billing_amount = self.billing_rate * self.hours + else: + self.billing_amount = 0 + + def update_project(self): + activity_cost = frappe.db.sql("""select sum(billing_cost) from `tabTime Log` + where project = %s and docstatus=1""",self.project) + frappe.db.set_value("Project", self.project, "total_activity_cost", activity_cost) @frappe.whitelist() def get_events(start, end, filters=None): @@ -243,3 +258,10 @@ def get_events(start, end, filters=None): d.title += " for Project: " + d.project return data + +@frappe.whitelist() +def get_activity_cost(employee=None, activity_type=None): + internal_rate = frappe.db.get_value("Activity Cost", {"employee":employee,"activity_type":activity_type}, "internal_rate") + billing_rate = frappe.db.get_value("Activity Cost", {"employee":employee,"activity_type":activity_type}, "billing_rate") + return {"internal_rate": internal_rate, "billing_rate": billing_rate } +