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
diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.json b/erpnext/projects/doctype/activity_cost/activity_cost.json
index 48c1247..0f37c5c 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,11 +25,19 @@
"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",
"permlevel": 0,
@@ -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 31df89a..efba0f6 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 c29dcc0..00e97f6 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 a49b1f1..e4fbfc3 100644
--- a/erpnext/projects/doctype/time_log/time_log.js
+++ b/erpnext/projects/doctype/time_log/time_log.js
@@ -41,4 +41,44 @@
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 217bc65..8b7c956 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",
@@ -224,6 +237,32 @@
"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",
"fieldtype": "Link",
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index 36bf5a7..de37912 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -24,12 +24,15 @@
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 @@
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 @@
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 }
+