Merge pull request #3006 from neilLasrado/project

Project Costing 
diff --git a/erpnext/config/projects.py b/erpnext/config/projects.py
index d591c9e..07149e3 100644
--- a/erpnext/config/projects.py
+++ b/erpnext/config/projects.py
@@ -32,6 +32,11 @@
 					"name": "Activity Type",
 					"description": _("Types of activities for Time Sheets"),
 				},
+				{
+					"type": "doctype",
+					"name": "Activity Cost",
+					"description": _("Cost of various activities"),
+				},
 			]
 		},
 		{
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 8076bf7..d279074 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -133,12 +133,14 @@
 cur_frm.cscript.calculate_total_amount = function(doc,cdt,cdn){
 	cur_frm.cscript.calculate_total(doc,cdt,cdn);
 }
+
 cur_frm.cscript.claim_amount = function(doc,cdt,cdn){
 	cur_frm.cscript.calculate_total(doc,cdt,cdn);
 
 	var child = locals[cdt][cdn];
 	refresh_field("sanctioned_amount", child.name, child.parentfield);
 }
+
 cur_frm.cscript.sanctioned_amount = function(doc,cdt,cdn){
 	cur_frm.cscript.calculate_total(doc,cdt,cdn);
 }
@@ -148,3 +150,30 @@
 		cur_frm.email_doc(frappe.boot.notification_settings.expense_claim_message);
 	}
 }
+
+erpnext.expense_claim = {
+	set_title :function(frm) {
+		if (!frm.doc.task) {
+			frm.set_value("title", frm.doc.employee_name);
+		}
+		else {
+			frm.set_value("title", frm.doc.employee_name + " for "+ frm.doc.task);
+		}
+	}
+}
+
+frappe.ui.form.on("Expense Claim", "employee_name", function(frm) {
+	erpnext.expense_claim.set_title(frm);
+});
+
+frappe.ui.form.on("Expense Claim", "task", function(frm) {
+	erpnext.expense_claim.set_title(frm);
+});
+
+cur_frm.fields_dict['task'].get_query = function(doc) {
+	return {
+		filters:{
+			'project': doc.project
+		}
+	}	
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index ef3d617..e08856a 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -93,7 +93,8 @@
    "oldfieldname": "expense_voucher_details", 
    "oldfieldtype": "Table", 
    "options": "Expense Claim Detail", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "reqd": 1
   }, 
   {
    "fieldname": "sb1", 
@@ -102,6 +103,7 @@
    "permlevel": 0
   }, 
   {
+   "default": "Today", 
    "fieldname": "posting_date", 
    "fieldtype": "Date", 
    "in_filter": 1, 
@@ -192,6 +194,21 @@
    "precision": ""
   }, 
   {
+   "fieldname": "task", 
+   "fieldtype": "Link", 
+   "label": "Task", 
+   "options": "Task", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "title", 
+   "fieldtype": "Data", 
+   "label": "Title", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "email_id", 
    "fieldtype": "Data", 
    "hidden": 1, 
@@ -220,7 +237,7 @@
  "icon": "icon-money", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-03-26 04:41:50.473196", 
+ "modified": "2015-04-22 01:51:24.782515", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Expense Claim", 
@@ -294,5 +311,5 @@
  "search_fields": "approval_status,employee,employee_name", 
  "sort_field": "modified", 
  "sort_order": "DESC", 
- "title_field": "employee_name"
+ "title_field": "title"
 }
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index 76606e5..6687399 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.utils import get_fullname
+from frappe.utils import get_fullname, flt
 from frappe.model.document import Document
 from erpnext.hr.utils import set_employee_name
 from erpnext.accounts.utils import validate_fiscal_year
@@ -18,19 +18,44 @@
 
 	def validate(self):
 		validate_fiscal_year(self.posting_date, self.fiscal_year, _("Posting Date"), self)
-		self.validate_exp_details()
+		self.validate_sanctioned_amount()
 		self.validate_expense_approver()
+		self.validate_task()
+		self.calculate_total_amount()
 		set_employee_name(self)
 
 	def on_submit(self):
 		if self.approval_status=="Draft":
 			frappe.throw(_("""Approval Status must be 'Approved' or 'Rejected'"""))
-
-	def validate_exp_details(self):
-		if not self.get('expenses'):
-			frappe.throw(_("Please add expense voucher details"))
+		if self.task:
+			self.update_task()
+			
+	def on_cancel(self):
+		if self.task:
+			self.update_task()
+			
+	def calculate_total_amount(self):
+		self.total_claimed_amount = 0 
+		self.total_sanctioned_amount = 0
+		for d in self.get('expenses'):
+			self.total_claimed_amount += flt(d.claim_amount)
+			self.total_sanctioned_amount += flt(d.sanctioned_amount)
 
 	def validate_expense_approver(self):
 		if self.exp_approver and "Expense Approver" not in frappe.get_roles(self.exp_approver):
 			frappe.throw(_("{0} ({1}) must have role 'Expense Approver'")\
 				.format(get_fullname(self.exp_approver), self.exp_approver), InvalidExpenseApproverError)
+	
+	def update_task(self):
+		task = frappe.get_doc("Task", self.task)
+		task.update_total_expense_claim()
+		task.save()
+
+	def validate_task(self):
+		if self.project and not self.task:
+			frappe.throw(_("Task is mandatory if Expense Claim is against a Project"))
+
+	def validate_sanctioned_amount(self):
+		for d in self.get('expenses'):
+			if flt(d.sanctioned_amount) > flt(d.claim_amount):
+				frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx))
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index f1c657a..a9091fb 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -8,4 +8,47 @@
 test_records = frappe.get_test_records('Expense Claim')
 
 class TestExpenseClaim(unittest.TestCase):
-	pass
+	def test_total_expense_claim_for_project(self):
+		frappe.db.sql("""delete from `tabTask` where project = "_Test Project 1" """)
+		frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
+		
+		frappe.get_doc({
+			"project_name": "_Test Project 1",
+			"doctype": "Project",
+			"tasks" :
+				[{ "title": "_Test Project Task 1", "status": "Open" }]
+		}).save()
+		
+		task_name = frappe.db.get_value("Task",{"project": "_Test Project 1"})
+		expense_claim = frappe.get_doc({
+			 "doctype": "Expense Claim",
+			 "employee": "_T-Employee-0001",
+			 "approval_status": "Approved",
+			 "project": "_Test Project 1",
+			 "task": task_name,
+			 "expenses": 
+			 	[{ "expense_type": "Food", "claim_amount": 300, "sanctioned_amount": 200 }]
+		})
+		expense_claim.submit()
+		
+		self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
+		self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
+		
+		expense_claim2 = frappe.get_doc({
+			 "doctype": "Expense Claim",
+			 "employee": "_T-Employee-0001",
+			 "approval_status": "Approved",
+			 "project": "_Test Project 1",
+			 "task": task_name,
+			 "expenses": 
+			 	[{ "expense_type": "Food", "claim_amount": 600, "sanctioned_amount": 500 }]
+		})
+		expense_claim2.submit()
+		
+		self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 700)
+		self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 700)
+		
+		expense_claim2.cancel()
+		
+		self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
+		self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
diff --git a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
index d975189..c6123ee 100644
--- a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
+++ b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
@@ -16,6 +16,12 @@
    "width": "150px"
   }, 
   {
+   "fieldname": "column_break_2", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "expense_type", 
    "fieldtype": "Link", 
    "in_list_view": 1, 
@@ -29,6 +35,12 @@
    "width": "150px"
   }, 
   {
+   "fieldname": "section_break_4", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "description", 
    "fieldtype": "Small Text", 
    "in_list_view": 1, 
@@ -40,6 +52,12 @@
    "width": "300px"
   }, 
   {
+   "fieldname": "section_break_6", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "claim_amount", 
    "fieldtype": "Currency", 
    "in_list_view": 1, 
@@ -53,6 +71,12 @@
    "width": "150px"
   }, 
   {
+   "fieldname": "column_break_8", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "allow_on_submit": 0, 
    "fieldname": "sanctioned_amount", 
    "fieldtype": "Currency", 
@@ -69,7 +93,7 @@
  ], 
  "idx": 1, 
  "istable": 1, 
- "modified": "2014-05-09 02:16:38.529082", 
+ "modified": "2015-04-08 06:18:47.539134", 
  "modified_by": "Administrator", 
  "module": "HR", 
  "name": "Expense Claim Detail", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 0e0fda9..0665df4 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -143,3 +143,4 @@
 erpnext.patches.v5_0.execute_on_doctype_update
 erpnext.patches.v4_2.fix_recurring_orders
 erpnext.patches.v4_2.delete_gl_entries_for_cancelled_invoices
+erpnext.patches.v5_0.project_costing
diff --git a/erpnext/patches/v5_0/project_costing.py b/erpnext/patches/v5_0/project_costing.py
new file mode 100644
index 0000000..33bb9c1
--- /dev/null
+++ b/erpnext/patches/v5_0/project_costing.py
@@ -0,0 +1,7 @@
+import frappe
+
+def execute():
+	frappe.reload_doctype("Project")
+	frappe.db.sql("update `tabProject` set expected_start_date = project_start_date, \
+		expected_end_date = completion_date, actual_end_date = act_completion_date, \
+		estimated_costing = project_value, gross_margin = gross_margin_value")
\ No newline at end of file
diff --git a/erpnext/projects/doctype/activity_cost/__init__.py b/erpnext/projects/doctype/activity_cost/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/projects/doctype/activity_cost/__init__.py
diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.json b/erpnext/projects/doctype/activity_cost/activity_cost.json
new file mode 100644
index 0000000..7f7720a
--- /dev/null
+++ b/erpnext/projects/doctype/activity_cost/activity_cost.json
@@ -0,0 +1,170 @@
+{
+ "allow_copy": 0, 
+ "allow_import": 1, 
+ "allow_rename": 1, 
+ "autoname": "Activity Cost - .#", 
+ "creation": "2015-03-23 02:00:21.861546", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "Master", 
+ "fields": [
+  {
+   "allow_on_submit": 0, 
+   "fieldname": "employee", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Employee", 
+   "no_copy": 0, 
+   "options": "Employee", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "read_only": 0, 
+   "report_hide": 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, 
+   "precision": ""
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "fieldname": "activity_type", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Activity Type", 
+   "no_copy": 0, 
+   "options": "Activity Type", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0
+  }, 
+  {
+   "fieldname": "section_break_4", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "default": "0", 
+   "description": "per hour", 
+   "fieldname": "billing_rate", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Billing Rate", 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0
+  }, 
+  {
+   "fieldname": "column_break_6", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "default": "0", 
+   "description": "per hour", 
+   "fieldname": "costing_rate", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Costing Rate", 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "read_only": 0, 
+   "report_hide": 0, 
+   "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, 
+ "hide_toolbar": 0, 
+ "in_create": 0, 
+ "in_dialog": 0, 
+ "is_submittable": 0, 
+ "issingle": 0, 
+ "istable": 0, 
+ "modified": "2015-04-14 02:08:33.690406", 
+ "modified_by": "Administrator", 
+ "module": "Projects", 
+ "name": "Activity Cost", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 0, 
+   "apply_user_permissions": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 1, 
+   "email": 1, 
+   "export": 1, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 1, 
+   "read": 1, 
+   "report": 1, 
+   "role": "Projects User", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }
+ ], 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "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
new file mode 100644
index 0000000..121e650
--- /dev/null
+++ b/erpnext/projects/doctype/activity_cost/activity_cost.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.model.document import Document
+
+class DuplicationError(frappe.ValidationError): pass
+
+class ActivityCost(Document):
+	def validate(self):
+		self.set_title()
+		self.check_unique()
+		
+	def set_title(self):
+		self.title = _("{0} for {1}").format(self.employee_name, self.activity_type)
+		
+	def check_unique(self):
+		if frappe.db.sql("""select name from `tabActivity Cost` where employee_name= %s and activity_type= %s and name != %s""",
+			(self.employee_name, self.activity_type, self.name)):
+				frappe.throw(_("Activity Cost exists for Employee {0} against Activity Type - {1}")
+					.format(self.employee, self.activity_type), DuplicationError)
diff --git a/erpnext/projects/doctype/activity_cost/test_activity_cost.py b/erpnext/projects/doctype/activity_cost/test_activity_cost.py
new file mode 100644
index 0000000..5afd97f
--- /dev/null
+++ b/erpnext/projects/doctype/activity_cost/test_activity_cost.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+from erpnext.projects.doctype.activity_cost.activity_cost import DuplicationError
+
+class TestActivityCost(unittest.TestCase):
+	def test_duplication(self):
+		frappe.db.sql("delete from `tabActivity Cost`")
+		activity_cost1 = frappe.new_doc('Activity Cost')
+		activity_cost1.update({
+			"employee": "_T-Employee-0001",
+			"employee_name": "_Test Employee",
+			"activity_type": "_Test Activity Type",
+			"billing_rate": 100,
+			"costing_rate": 50
+		})
+		activity_cost1.insert()
+		activity_cost2 = frappe.copy_doc(activity_cost1)
+		self.assertRaises(DuplicationError, activity_cost2.insert )
diff --git a/erpnext/projects/doctype/activity_cost/test_records.json b/erpnext/projects/doctype/activity_cost/test_records.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/erpnext/projects/doctype/activity_cost/test_records.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.js b/erpnext/projects/doctype/project/project.js
index eeedeb0..aa55876 100644
--- a/erpnext/projects/doctype/project/project.js
+++ b/erpnext/projects/doctype/project/project.js
@@ -1,6 +1,19 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
+frappe.ui.form.on("Project", {
+	onload: function(frm) {
+		var so = frappe.meta.get_docfield("Project", "sales_order");
+		so.get_route_options_for_new_doc = function(field) {
+			if(frm.is_new()) return;
+			return {
+				"customer": frm.doc.customer,
+				"project_name": frm.doc.name
+			}
+		}
+	}
+});
+
 frappe.ui.form.on("Project Task", "edit_task", function(frm, doctype, name) {
 	var doc = frappe.get_doc(doctype, name);
 	if(doc.task_id) {
@@ -14,13 +27,21 @@
 cur_frm.cscript.refresh = function(doc) {
 	if(!doc.__islocal) {
 		cur_frm.add_custom_button(__("Gantt Chart"), function() {
-			frappe.route_options = {"project": doc.name, "start": doc.project_start_date, "end": doc.completion_date};
+			frappe.route_options = {"project": doc.name, "start": doc.expected_start_date, "end": doc.expected_end_date};
 			frappe.set_route("Gantt", "Task");
 		}, "icon-tasks", true);
 		cur_frm.add_custom_button(__("Tasks"), function() {
 			frappe.route_options = {"project": doc.name}
 			frappe.set_route("List", "Task");
 		}, "icon-list", true);
+		cur_frm.add_custom_button(__("Time Logs"), function() {
+			frappe.route_options = {"project": doc.name}
+			frappe.set_route("List", "Time Log");
+		}, "icon-list", true);
+		cur_frm.add_custom_button(__("Expense Claims"), function() {
+			frappe.route_options = {"project": doc.name}
+			frappe.set_route("List", "Expense Claim");
+		}, "icon-list", true);
 	}
 }
 
@@ -29,3 +50,11 @@
 		query: "erpnext.controllers.queries.customer_query"
 	}
 }
+
+cur_frm.fields_dict['sales_order'].get_query = function(doc) {
+	return {
+		filters:{
+			'project_name': doc.name
+		}
+	}	
+}
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 6a143ab..5c4f7d1 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -8,19 +8,6 @@
  "document_type": "Master", 
  "fields": [
   {
-   "fieldname": "overview", 
-   "fieldtype": "Section Break", 
-   "label": "Overview", 
-   "options": "icon-file", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "cb_project_status", 
-   "fieldtype": "Column Break", 
-   "label": "Status", 
-   "permlevel": 0
-  }, 
-  {
    "description": "", 
    "fieldname": "project_name", 
    "fieldtype": "Data", 
@@ -46,6 +33,23 @@
    "search_index": 1
   }, 
   {
+   "fieldname": "project_type", 
+   "fieldtype": "Select", 
+   "label": "Project Type", 
+   "no_copy": 0, 
+   "oldfieldname": "project_type", 
+   "oldfieldtype": "Data", 
+   "options": "Internal\nExternal\nOther", 
+   "permlevel": 0, 
+   "search_index": 0
+  }, 
+  {
+   "fieldname": "column_break_5", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "is_active", 
    "fieldtype": "Select", 
    "label": "Is Active", 
@@ -69,16 +73,16 @@
    "search_index": 0
   }, 
   {
-   "fieldname": "cb_project_dates", 
-   "fieldtype": "Column Break", 
-   "label": "Dates", 
-   "permlevel": 0
+   "fieldname": "section_break_12", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
   }, 
   {
-   "fieldname": "project_start_date", 
+   "fieldname": "expected_start_date", 
    "fieldtype": "Date", 
    "in_filter": 1, 
-   "label": "Project Start Date", 
+   "label": "Expected Start Date", 
    "no_copy": 0, 
    "oldfieldname": "project_start_date", 
    "oldfieldtype": "Date", 
@@ -86,9 +90,15 @@
    "search_index": 0
   }, 
   {
-   "fieldname": "completion_date", 
+   "fieldname": "column_break_11", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "expected_end_date", 
    "fieldtype": "Date", 
-   "label": "Completion Date", 
+   "label": "Expected End Date", 
    "no_copy": 0, 
    "oldfieldname": "completion_date", 
    "oldfieldtype": "Date", 
@@ -96,25 +106,47 @@
    "search_index": 0
   }, 
   {
-   "fieldname": "act_completion_date", 
-   "fieldtype": "Date", 
-   "label": "Actual Completion Date", 
-   "no_copy": 0, 
-   "oldfieldname": "act_completion_date", 
-   "oldfieldtype": "Date", 
-   "permlevel": 0, 
-   "search_index": 0
+   "fieldname": "customer_details", 
+   "fieldtype": "Section Break", 
+   "label": "", 
+   "oldfieldtype": "Section Break", 
+   "options": "icon-user", 
+   "permlevel": 0
   }, 
   {
-   "fieldname": "project_type", 
-   "fieldtype": "Select", 
-   "label": "Project Type", 
+   "fieldname": "customer", 
+   "fieldtype": "Link", 
+   "in_filter": 1, 
+   "label": "Customer", 
    "no_copy": 0, 
-   "oldfieldname": "project_type", 
-   "oldfieldtype": "Data", 
-   "options": "Internal\nExternal\nOther", 
+   "oldfieldname": "customer", 
+   "oldfieldtype": "Link", 
+   "options": "Customer", 
    "permlevel": 0, 
-   "search_index": 0
+   "print_hide": 1, 
+   "reqd": 0, 
+   "search_index": 1
+  }, 
+  {
+   "fieldname": "company", 
+   "fieldtype": "Link", 
+   "label": "Company", 
+   "options": "Company", 
+   "permlevel": 0
+  }, 
+  {
+   "fieldname": "column_break_14", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "sales_order", 
+   "fieldtype": "Link", 
+   "label": "Sales Order", 
+   "options": "Sales Order", 
+   "permlevel": 0, 
+   "precision": ""
   }, 
   {
    "fieldname": "sb_milestones", 
@@ -130,7 +162,8 @@
    "label": "Tasks", 
    "options": "Project Task", 
    "permlevel": 0, 
-   "precision": ""
+   "precision": "", 
+   "reqd": 0
   }, 
   {
    "fieldname": "percent_complete", 
@@ -159,25 +192,55 @@
    "search_index": 0
   }, 
   {
-   "fieldname": "company", 
-   "fieldtype": "Link", 
-   "label": "Company", 
-   "options": "Company", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "project_details", 
+   "fieldname": "section_break_18", 
    "fieldtype": "Section Break", 
-   "label": "Project Costing", 
-   "oldfieldtype": "Section Break", 
-   "options": "icon-money", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "precision": ""
   }, 
   {
-   "fieldname": "project_value", 
+   "fieldname": "actual_start_date", 
+   "fieldtype": "Data", 
+   "label": "Actual Start Date", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "actual_time", 
+   "fieldtype": "Float", 
+   "label": "Actual Time (in Hours)", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "column_break_20", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "actual_end_date", 
+   "fieldtype": "Date", 
+   "label": "Actual End Date", 
+   "no_copy": 0, 
+   "oldfieldname": "act_completion_date", 
+   "oldfieldtype": "Date", 
+   "permlevel": 0, 
+   "read_only": 1, 
+   "search_index": 0
+  }, 
+  {
+   "fieldname": "section_break_26", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "estimated_costing", 
    "fieldtype": "Currency", 
    "in_list_view": 1, 
-   "label": "Project Value", 
+   "label": "Estimated Costing", 
    "no_copy": 0, 
    "oldfieldname": "project_value", 
    "oldfieldtype": "Currency", 
@@ -187,15 +250,10 @@
    "search_index": 0
   }, 
   {
-   "fieldname": "est_material_cost", 
-   "fieldtype": "Currency", 
-   "label": "Estimated Material Cost", 
-   "no_copy": 0, 
-   "oldfieldname": "est_material_cost", 
-   "oldfieldtype": "Currency", 
-   "options": "Company:company:default_currency", 
+   "fieldname": "column_break_22", 
+   "fieldtype": "Column Break", 
    "permlevel": 0, 
-   "search_index": 0
+   "precision": ""
   }, 
   {
    "fieldname": "cost_center", 
@@ -205,64 +263,91 @@
    "permlevel": 0
   }, 
   {
-   "fieldname": "column_break0", 
+   "fieldname": "project_details", 
+   "fieldtype": "Section Break", 
+   "label": "", 
+   "oldfieldtype": "Section Break", 
+   "options": "icon-money", 
+   "permlevel": 0
+  }, 
+  {
+   "description": "", 
+   "fieldname": "total_costing_amount", 
+   "fieldtype": "Currency", 
+   "label": "Total Costing Amount (via Time Logs)", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "description": "", 
+   "fieldname": "total_expense_claim", 
+   "fieldtype": "Currency", 
+   "label": "Total Expense Claim (via Expense Claims)", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "column_break_28", 
    "fieldtype": "Column Break", 
-   "label": "Margin", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "description": "", 
+   "fieldname": "total_billing_amount", 
+   "fieldtype": "Currency", 
+   "label": "Total Billing Amount (via Time Logs)", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "margin", 
+   "fieldtype": "Section Break", 
+   "label": "", 
    "oldfieldtype": "Column Break", 
    "permlevel": 0, 
    "width": "50%"
   }, 
   {
-   "fieldname": "gross_margin_value", 
+   "fieldname": "gross_margin", 
    "fieldtype": "Currency", 
-   "label": "Gross Margin Value", 
+   "label": "Gross Margin", 
    "no_copy": 0, 
    "oldfieldname": "gross_margin_value", 
    "oldfieldtype": "Currency", 
    "options": "Company:company:default_currency", 
    "permlevel": 0, 
+   "read_only": 1, 
    "reqd": 0, 
    "search_index": 0
   }, 
   {
+   "fieldname": "column_break_37", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "per_gross_margin", 
-   "fieldtype": "Currency", 
+   "fieldtype": "Percent", 
    "label": "Gross Margin %", 
    "no_copy": 0, 
    "oldfieldname": "per_gross_margin", 
    "oldfieldtype": "Currency", 
-   "options": "Company:company:default_currency", 
+   "options": "", 
    "permlevel": 0, 
+   "read_only": 1, 
    "reqd": 0, 
    "search_index": 0
-  }, 
-  {
-   "fieldname": "customer_details", 
-   "fieldtype": "Section Break", 
-   "label": "Customer Details", 
-   "oldfieldtype": "Section Break", 
-   "options": "icon-user", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "customer", 
-   "fieldtype": "Link", 
-   "in_filter": 1, 
-   "label": "Customer", 
-   "no_copy": 0, 
-   "oldfieldname": "customer", 
-   "oldfieldtype": "Link", 
-   "options": "Customer", 
-   "permlevel": 0, 
-   "print_hide": 1, 
-   "reqd": 0, 
-   "search_index": 1
   }
  ], 
  "icon": "icon-puzzle-piece", 
  "idx": 1, 
  "max_attachments": 4, 
- "modified": "2015-02-22 11:17:49.051755", 
+ "modified": "2015-04-14 07:37:56.810833", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Project", 
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index c142180..89cf523 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -25,23 +25,19 @@
 				"task_id": task.name
 			})
 
-	def get_gross_profit(self):
-		pft, per_pft =0, 0
-		pft = flt(self.project_value) - flt(self.est_material_cost)
-		#if pft > 0:
-		per_pft = (flt(pft) / flt(self.project_value)) * 100
-		ret = {'gross_margin_value': pft, 'per_gross_margin': per_pft}
-		return ret
-
 	def validate(self):
-		if self.project_start_date and self.completion_date:
-			if getdate(self.completion_date) < getdate(self.project_start_date):
-				frappe.throw(_("Expected Completion Date can not be less than Project Start Date"))
-
+		self.validate_dates()
 		self.sync_tasks()
 
+	def validate_dates(self):
+		if self.expected_start_date and self.expected_end_date:
+			if getdate(self.expected_end_date) < getdate(self.expected_start_date):
+				frappe.throw(_("Expected End Date can not be less than Expected Start Date"))
+
 	def sync_tasks(self):
 		"""sync tasks and remove table"""
+		if self.flags.dont_sync_tasks: return
+		
 		task_names = []
 		for t in self.tasks:
 			if t.task_id:
@@ -66,7 +62,7 @@
 		# delete
 		for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
 			frappe.delete_doc("Task", t.name)
-
+		
 		self.tasks = []
 
 	def update_percent_complete(self):
@@ -77,7 +73,22 @@
 				project=%s and status in ('Closed', 'Cancelled')""", self.name)[0][0]
 			frappe.db.set_value("Project", self.name, "percent_complete",
 			 	int(float(completed) / total * 100))
-
+				
+	def update_costing(self):
+		total_cost = frappe.db.sql("""select sum(total_costing_amount) as costing_amount,
+			sum(total_billing_amount) as billing_amount, sum(total_expense_claim) as expense_claim,
+			min(act_start_date) as start_date, max(act_end_date) as end_date, sum(actual_time) as time
+			from `tabTask` where project = %s""", self.name, as_dict=1)[0]
+			
+		self.total_costing_amount = total_cost.costing_amount
+		self.total_billing_amount = total_cost.billing_amount
+		self.total_expense_claim = total_cost.expense_claim
+		self.actual_start_date = total_cost.start_date
+		self.actual_end_date = total_cost.end_date
+		self.actual_time = total_cost.time
+		self.gross_margin = flt(total_cost.billing_amount) - flt(total_cost.costing_amount)
+		if self.total_billing_amount:
+			self.per_gross_margin = (self.gross_margin / flt(self.total_billing_amount)) *100
 
 @frappe.whitelist()
 def get_cost_center_name(project_name):
diff --git a/erpnext/projects/doctype/project/project_list.js b/erpnext/projects/doctype/project/project_list.js
index 8281c7d..b0d1ae8 100644
--- a/erpnext/projects/doctype/project/project_list.js
+++ b/erpnext/projects/doctype/project/project_list.js
@@ -1,5 +1,5 @@
 frappe.listview_settings['Project'] = {
-	add_fields: ["status", "priority", "is_active", "percent_complete", "completion_date"],
+	add_fields: ["status", "priority", "is_active", "percent_complete", "expected_end_date"],
 	filters:[["status","=", "Open"]],
 	get_indicator: function(doc) {
 		if(doc.status=="Open" && doc.percent_complete) {
diff --git a/erpnext/projects/doctype/project/test_project.py b/erpnext/projects/doctype/project/test_project.py
index 744d6b4..f69ce80 100644
--- a/erpnext/projects/doctype/project/test_project.py
+++ b/erpnext/projects/doctype/project/test_project.py
@@ -5,4 +5,3 @@
 
 import frappe
 test_records = frappe.get_test_records('Project')
-test_ignore = ["Task"]
diff --git a/erpnext/projects/doctype/project/test_records.json b/erpnext/projects/doctype/project/test_records.json
index 69226f0..9379c22 100644
--- a/erpnext/projects/doctype/project/test_records.json
+++ b/erpnext/projects/doctype/project/test_records.json
@@ -1,10 +1,12 @@
 [
  {
-  "project_name": "_Test Project", 
-  "status": "Open"
- }, 
- {
-  "project_name": "_Test Project 1", 
-  "status": "Open"
+  "project_name": "_Test Project",
+  "status": "Open",
+  "tasks":[ 
+   {
+	  "title": "_Test Task",
+	  "status": "Open"
+   }
+  ]
  }
 ]
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project_task/project_task.json b/erpnext/projects/doctype/project_task/project_task.json
index c29dcc0..f3d2c66 100644
--- a/erpnext/projects/doctype/project_task/project_task.json
+++ b/erpnext/projects/doctype/project_task/project_task.json
@@ -37,7 +37,7 @@
    "in_filter": 0, 
    "in_list_view": 1, 
    "label": "Status", 
-   "no_copy": 0, 
+   "no_copy": 1, 
    "options": "Open\nWorking\nPending Review\nClosed\nCancelled", 
    "permlevel": 0, 
    "precision": "", 
@@ -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-04-13 04:56:18.766659", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Project Task", 
diff --git a/erpnext/projects/doctype/task/task.js b/erpnext/projects/doctype/task/task.js
index 51aabca..9756331 100644
--- a/erpnext/projects/doctype/task/task.js
+++ b/erpnext/projects/doctype/task/task.js
@@ -25,6 +25,19 @@
 		this.frm.doc.project && frappe.model.remove_from_locals("Project",
 			this.frm.doc.project);
 	},
+	
+	refresh: function(doc) {
+		if(!doc.__islocal) {
+			cur_frm.add_custom_button(__("Time Logs"), function() {
+				frappe.route_options = {"project": doc.project, "task": doc.name}
+				frappe.set_route("List", "Time Log");
+			}, "icon-list", true);
+			cur_frm.add_custom_button(__("Expense Claims"), function() {
+				frappe.route_options = {"project": doc.project, "task": doc.name}
+				frappe.set_route("List", "Expense Claim");
+			}, "icon-list", true);
+		}
+	}
 });
 
 
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index e547834..fc604c2 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -7,16 +7,6 @@
  "document_type": "Master", 
  "fields": [
   {
-   "fieldname": "task_details", 
-   "fieldtype": "Section Break", 
-   "label": "", 
-   "oldfieldtype": "Section Break", 
-   "permlevel": 0, 
-   "print_width": "50%", 
-   "search_index": 0, 
-   "width": "50%"
-  }, 
-  {
    "fieldname": "subject", 
    "fieldtype": "Data", 
    "in_filter": 1, 
@@ -28,24 +18,14 @@
    "reqd": 1
   }, 
   {
-   "fieldname": "exp_start_date", 
-   "fieldtype": "Date", 
-   "label": "Expected Start Date", 
-   "oldfieldname": "exp_start_date", 
-   "oldfieldtype": "Date", 
-   "permlevel": 0, 
-   "reqd": 0
-  }, 
-  {
-   "fieldname": "exp_end_date", 
-   "fieldtype": "Date", 
-   "in_filter": 1, 
-   "label": "Expected End Date", 
-   "oldfieldname": "exp_end_date", 
-   "oldfieldtype": "Date", 
-   "permlevel": 0, 
-   "reqd": 0, 
-   "search_index": 1
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "in_list_view": 1, 
+   "label": "Project", 
+   "oldfieldname": "project", 
+   "oldfieldtype": "Link", 
+   "options": "Project", 
+   "permlevel": 0
   }, 
   {
    "fieldname": "column_break0", 
@@ -67,16 +47,6 @@
    "permlevel": 0
   }, 
   {
-   "fieldname": "project", 
-   "fieldtype": "Link", 
-   "in_list_view": 1, 
-   "label": "Project", 
-   "oldfieldname": "project", 
-   "oldfieldtype": "Link", 
-   "options": "Project", 
-   "permlevel": 0
-  }, 
-  {
    "fieldname": "priority", 
    "fieldtype": "Select", 
    "in_filter": 1, 
@@ -110,41 +80,52 @@
   {
    "fieldname": "time_and_budget", 
    "fieldtype": "Section Break", 
-   "label": "Time and Budget", 
+   "label": "", 
    "oldfieldtype": "Section Break", 
    "permlevel": 0
   }, 
   {
-   "fieldname": "expected", 
-   "fieldtype": "Column Break", 
-   "label": "Expected", 
-   "oldfieldtype": "Column Break", 
+   "fieldname": "exp_start_date", 
+   "fieldtype": "Date", 
+   "label": "Expected Start Date", 
+   "oldfieldname": "exp_start_date", 
+   "oldfieldtype": "Date", 
    "permlevel": 0, 
-   "print_width": "50%", 
-   "width": "50%"
+   "reqd": 0
   }, 
   {
-   "fieldname": "exp_total_hrs", 
-   "fieldtype": "Data", 
-   "label": "Total Hours (Expected)", 
+   "default": "0", 
+   "description": "", 
+   "fieldname": "expected_time", 
+   "fieldtype": "Float", 
+   "label": "Expected Time (in hours)", 
    "oldfieldname": "exp_total_hrs", 
    "oldfieldtype": "Data", 
    "permlevel": 0, 
    "reqd": 0
   }, 
   {
-   "fieldname": "allocated_budget", 
-   "fieldtype": "Currency", 
-   "label": "Allocated Budget", 
-   "oldfieldname": "allocated_budget", 
-   "oldfieldtype": "Currency", 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0
+   "fieldname": "column_break_11", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
   }, 
   {
+   "fieldname": "exp_end_date", 
+   "fieldtype": "Date", 
+   "in_filter": 1, 
+   "label": "Expected End Date", 
+   "oldfieldname": "exp_end_date", 
+   "oldfieldtype": "Date", 
+   "permlevel": 0, 
+   "reqd": 0, 
+   "search_index": 1
+  }, 
+  {
+   "description": "", 
    "fieldname": "actual", 
-   "fieldtype": "Column Break", 
-   "label": "Actual", 
+   "fieldtype": "Section Break", 
+   "label": "", 
    "oldfieldtype": "Column Break", 
    "permlevel": 0, 
    "print_width": "50%", 
@@ -153,27 +134,77 @@
   {
    "fieldname": "act_start_date", 
    "fieldtype": "Date", 
-   "label": "Actual Start Date", 
+   "label": "Actual Start Date (via Time Logs)", 
    "oldfieldname": "act_start_date", 
    "oldfieldtype": "Date", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "read_only": 1
+  }, 
+  {
+   "default": "", 
+   "description": "", 
+   "fieldname": "actual_time", 
+   "fieldtype": "Float", 
+   "label": "Actual Time (in hours)", 
+   "options": "", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "column_break_15", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
   }, 
   {
    "fieldname": "act_end_date", 
    "fieldtype": "Date", 
-   "label": "Actual End Date", 
+   "label": "Actual End Date (via Time Logs)", 
    "oldfieldname": "act_end_date", 
    "oldfieldtype": "Date", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "read_only": 1
   }, 
   {
-   "fieldname": "actual_budget", 
+   "fieldname": "section_break_17", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "total_costing_amount", 
    "fieldtype": "Currency", 
-   "label": "Actual Budget", 
+   "label": "Total Costing Amount (via Time Logs)", 
    "oldfieldname": "actual_budget", 
    "oldfieldtype": "Currency", 
    "options": "Company:company:default_currency", 
-   "permlevel": 0
+   "permlevel": 0, 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "total_expense_claim", 
+   "fieldtype": "Currency", 
+   "label": "Total Expense Claim (via Expense Claim)", 
+   "options": "Company:company:default_currency", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "column_break_20", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "total_billing_amount", 
+   "fieldtype": "Currency", 
+   "hidden": 0, 
+   "label": "Total Billing Amount (via Time Logs)", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
   }, 
   {
    "fieldname": "more_details", 
@@ -216,8 +247,9 @@
  ], 
  "icon": "icon-check", 
  "idx": 1, 
+ "istable": 0, 
  "max_attachments": 5, 
- "modified": "2015-02-20 05:09:27.295024", 
+ "modified": "2015-04-14 07:56:24.481667", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Task", 
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index acd0877..a03340f 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import frappe, json
 
-from frappe.utils import getdate, today
+from frappe.utils import getdate
 from frappe import _
 
 
@@ -26,27 +26,48 @@
 			return ret
 
 	def validate(self):
+		self.validate_dates()
+		
+	def validate_dates(self):
 		if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
 			frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'"))
 
 		if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
 			frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'"))
 
-		self.update_status()
-
-	def update_status(self):
-		status = frappe.db.get_value("Task", self.name, "status")
-		if self.status=="Working" and status !="Working" and not self.act_start_date:
-			self.act_start_date = today()
-
-		if self.status=="Closed" and status != "Closed" and not self.act_end_date:
-			self.act_end_date = today()
-
 	def on_update(self):
+		self.update_percentage()
+		self.update_project()
+			
+	def update_percentage(self):
 		"""update percent complete in project"""
 		if self.project and not self.flags.from_project:
 			project = frappe.get_doc("Project", self.project)
 			project.run_method("update_percent_complete")
+			
+	def update_total_expense_claim(self):
+		self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim` 
+			where project = %s and task = %s and approval_status = "Approved" and docstatus=1""",(self.project, self.name))
+			
+	def update_time_and_costing(self):
+		tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date,
+			 sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount,
+			sum(hours) as time from `tabTime Log` where project = %s and task = %s and docstatus=1""",
+			(self.project, self.name),as_dict=1)[0]
+		if self.status == "Open":
+			self.status = "Working"
+		self.total_costing_amount= tl.total_costing_amount
+		self.total_billing_amount= tl.total_billing_amount
+		self.actual_time= tl.time
+		self.act_start_date= tl.start_date
+		self.act_end_date= tl.end_date
+			
+	def update_project(self):
+		if self.project and frappe.db.exists("Project", self.project):
+			project = frappe.get_doc("Project", self.project)
+			project.flags.dont_sync_tasks = True
+			project.update_costing()
+			project.save()
 
 @frappe.whitelist()
 def get_events(start, end, filters=None):
diff --git a/erpnext/projects/doctype/task/test_records.json b/erpnext/projects/doctype/task/test_records.json
index 1f98172..42ca0e7 100644
--- a/erpnext/projects/doctype/task/test_records.json
+++ b/erpnext/projects/doctype/task/test_records.json
@@ -1,8 +1,8 @@
 [
  {
-  "project": "_Test Project", 
   "status": "Open", 
-  "subject": "_Test Task"
+  "subject": "_Test Task",
+  "name": "task001"
  }, 
  {
   "status": "Open", 
diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py
index 6f75e0d..62e560f 100644
--- a/erpnext/projects/doctype/task/test_task.py
+++ b/erpnext/projects/doctype/task/test_task.py
@@ -5,5 +5,3 @@
 
 import frappe
 test_records = frappe.get_test_records('Task')
-test_dependencies = ["Project"]
-test_ignore = ["Customer"]
diff --git a/erpnext/projects/doctype/time_log/test_records.json b/erpnext/projects/doctype/time_log/test_records.json
index d9e67e9..568c012 100644
--- a/erpnext/projects/doctype/time_log/test_records.json
+++ b/erpnext/projects/doctype/time_log/test_records.json
@@ -5,7 +5,6 @@
   "doctype": "Time Log",
   "from_time": "2013-01-01 10:00:00.000000",
   "note": "_Test Note",
-  "to_time": "2013-01-01 11:00:00.000000",
-  "project": "_Test Project"
+  "to_time": "2013-01-01 11:00:00.000000"
  }
 ]
diff --git a/erpnext/projects/doctype/time_log/test_time_log.py b/erpnext/projects/doctype/time_log/test_time_log.py
index 8f8e31d..3d9e0be 100644
--- a/erpnext/projects/doctype/time_log/test_time_log.py
+++ b/erpnext/projects/doctype/time_log/test_time_log.py
@@ -10,7 +10,6 @@
 from erpnext.projects.doctype.time_log.time_log import NotSubmittedError
 from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
 from erpnext.manufacturing.doctype.workstation.workstation import NotInWorkingHoursError
-from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
 from erpnext.manufacturing.doctype.production_order.test_production_order import make_prod_order_test_record
 
 
@@ -85,6 +84,72 @@
 		test_time_log.to_time = "2013-01-01 10:00:00.000000"
 		self.assertRaises(frappe.ValidationError, test_time_log.save)
 		frappe.db.sql("delete from `tabTime Log`")
-
+		
+	def test_total_activity_cost_for_project(self):
+		frappe.db.sql("""delete from `tabTask` where project = "_Test Project 1" """)
+		frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
+		frappe.db.sql("""delete from `tabActivity Cost` where employee = "_T-Employee-0001" and activity_type = "_Test Activity Type" """)
+		
+		activity_cost = frappe.new_doc('Activity Cost')
+		activity_cost.update({
+			"employee": "_T-Employee-0001",
+			"employee_name": "_Test Employee",
+			"activity_type": "_Test Activity Type",
+			"billing_rate": 100,
+			"costing_rate": 50
+		})
+		activity_cost.insert()
+		
+		frappe.get_doc({
+			"project_name": "_Test Project 1",
+			"doctype": "Project",
+			"tasks" :
+				[{ "title": "_Test Project Task 1", "status": "Open" }]
+		}).save()
+		
+		task_name = frappe.db.get_value("Task",{"project": "_Test Project 1"})
+		
+		time_log = frappe.get_doc({
+			 "activity_type": "_Test Activity Type",
+			 "docstatus": 1,
+			 "doctype": "Time Log",
+			 "from_time": "2013-02-02 09:00:00.000000",
+			 "to_time": "2013-02-02 11:00:00.000000",
+			 "employee": "_T-Employee-0001",
+			 "project": "_Test Project 1",
+			 "task": task_name,
+			 "billable": 1
+		})
+		time_log.save()
+		self.assertEqual(time_log.costing_rate, 50)
+		self.assertEqual(time_log.costing_amount, 100)
+		self.assertEqual(time_log.billing_rate, 100)
+		self.assertEqual(time_log.billing_amount, 200)
+		time_log.submit()
+		
+		self.assertEqual(frappe.db.get_value("Task", task_name, "total_billing_amount"), 200)
+		self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_billing_amount"), 200)
+		
+		time_log2 = frappe.get_doc({
+			 "activity_type": "_Test Activity Type",
+			 "docstatus": 1,
+			 "doctype": "Time Log",
+			 "from_time": "2013-02-03 09:00:00.000000",
+			 "to_time": "2013-02-03 11:00:00.000000",
+			 "employee": "_T-Employee-0001",
+			 "project": "_Test Project 1",
+			 "task": task_name,
+			 "billable": 1
+		})
+		time_log2.save()
+		
+		self.assertEqual(frappe.db.get_value("Task", task_name, "total_billing_amount"), 400)
+		self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_billing_amount"), 400)
+		
+		time_log2.cancel()
+		
+		self.assertEqual(frappe.db.get_value("Task", task_name, "total_billing_amount"), 200)
+		self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_billing_amount"), 200)
+		
 test_records = frappe.get_test_records('Time Log')
 test_ignore = ["Time Log Batch", "Sales Invoice"]
diff --git a/erpnext/projects/doctype/time_log/time_log.js b/erpnext/projects/doctype/time_log/time_log.js
index a49b1f1..ba93301 100644
--- a/erpnext/projects/doctype/time_log/time_log.js
+++ b/erpnext/projects/doctype/time_log/time_log.js
@@ -4,7 +4,6 @@
 frappe.provide("erpnext.projects");
 
 frappe.ui.form.on("Time Log", "onload", function(frm) {
-	frm.set_query("task", erpnext.queries.task);
 	if (frm.doc.for_manufacturing) {
 		frappe.ui.form.trigger("Time Log", "production_order");
 	}
@@ -41,4 +40,60 @@
 	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(frm) {
+	frm.set_value("costing_amount", frm.doc.costing_rate * frm.doc.hours);
+	if (frm.doc.billable==1){
+		frm.set_value("billing_amount", frm.doc.billing_rate * frm.doc.hours);
+	}
+}
+
+var get_activity_cost = function(frm) {
+	if (frm.doc.employee && frm.doc.activity_type){
+		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 && r.message) {
+					frm.set_value("costing_rate", r.message.costing_rate);
+					frm.set_value("billing_rate", r.message.billing_rate);
+					calculate_cost(frm);
+				}
+			}
+		});
+	}
+}
+
+frappe.ui.form.on("Time Log", "hours", function(frm) {
+	calculate_cost(frm);
+});
+
+frappe.ui.form.on("Time Log", "activity_type", function(frm) {
+	get_activity_cost(frm);
+});
+
+frappe.ui.form.on("Time Log", "employee", function(frm) {
+	get_activity_cost(frm);
+});
+
+frappe.ui.form.on("Time Log", "billable", function(frm) {
+	if (frm.doc.billable==1) {
+		calculate_cost(frm);
+	}
+	else {
+		frm.set_value("billing_amount", 0);
+	}
+});
+
+cur_frm.fields_dict['task'].get_query = function(doc) {
+	return {
+		filters:{
+			'project': doc.project
+		}
+	}	
+}
diff --git a/erpnext/projects/doctype/time_log/time_log.json b/erpnext/projects/doctype/time_log/time_log.json
index 20b5c0c..e9e2077 100644
--- a/erpnext/projects/doctype/time_log/time_log.json
+++ b/erpnext/projects/doctype/time_log/time_log.json
@@ -17,44 +17,10 @@
    "reqd": 1
   }, 
   {
-   "fieldname": "from_time", 
-   "fieldtype": "Datetime", 
-   "in_list_view": 0, 
-   "label": "From Time", 
-   "permlevel": 0, 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "to_time", 
-   "fieldtype": "Datetime", 
-   "in_list_view": 0, 
-   "label": "To Time", 
-   "permlevel": 0, 
-   "read_only": 0, 
-   "reqd": 1
-  }, 
-  {
-   "fieldname": "hours", 
-   "fieldtype": "Float", 
-   "in_list_view": 1, 
-   "label": "Hours", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
-   "fieldname": "user", 
-   "fieldtype": "Link", 
-   "label": "User", 
-   "options": "User", 
-   "permlevel": 0, 
-   "precision": ""
-  }, 
-  {
-   "fieldname": "column_break_3", 
+   "fieldname": "column_break_2", 
    "fieldtype": "Column Break", 
    "permlevel": 0, 
-   "read_only": 0
+   "precision": ""
   }, 
   {
    "fieldname": "status", 
@@ -67,20 +33,62 @@
    "reqd": 0
   }, 
   {
-   "fieldname": "billable", 
-   "fieldtype": "Check", 
+   "fieldname": "section_break_4", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "from_time", 
+   "fieldtype": "Datetime", 
    "in_list_view": 0, 
-   "label": "Billable", 
+   "label": "From Time", 
+   "permlevel": 0, 
+   "read_only": 0, 
+   "reqd": 1
+  }, 
+  {
+   "default": "0", 
+   "fieldname": "hours", 
+   "fieldtype": "Float", 
+   "in_list_view": 1, 
+   "label": "Hours", 
    "permlevel": 0, 
    "read_only": 0
   }, 
   {
-   "fieldname": "for_manufacturing", 
-   "fieldtype": "Check", 
-   "label": "For Manufacturing", 
+   "fieldname": "to_time", 
+   "fieldtype": "Datetime", 
+   "in_list_view": 0, 
+   "label": "To Time", 
    "permlevel": 0, 
-   "precision": "", 
-   "read_only": 1
+   "read_only": 0, 
+   "reqd": 1
+  }, 
+  {
+   "fieldname": "column_break_8", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "depends_on": "", 
+   "fieldname": "project", 
+   "fieldtype": "Link", 
+   "in_list_view": 1, 
+   "label": "Project", 
+   "options": "Project", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
+   "depends_on": "", 
+   "fieldname": "task", 
+   "fieldtype": "Link", 
+   "label": "Task", 
+   "options": "Task", 
+   "permlevel": 0, 
+   "read_only": 0
   }, 
   {
    "depends_on": "eval:!doc.for_manufacturing", 
@@ -94,11 +102,47 @@
    "reqd": 0
   }, 
   {
-   "depends_on": "eval:!doc.for_manufacturing", 
-   "fieldname": "task", 
+   "fieldname": "section_break_12", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "user", 
    "fieldtype": "Link", 
-   "label": "Task", 
-   "options": "Task", 
+   "label": "User", 
+   "options": "User", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "employee", 
+   "fieldtype": "Link", 
+   "label": "Employee", 
+   "options": "Employee", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "fieldname": "column_break_3", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "read_only": 0
+  }, 
+  {
+   "fieldname": "for_manufacturing", 
+   "fieldtype": "Check", 
+   "hidden": 1, 
+   "label": "For Manufacturing", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "billable", 
+   "fieldtype": "Check", 
+   "in_list_view": 0, 
+   "label": "Billable", 
    "permlevel": 0, 
    "read_only": 0
   }, 
@@ -180,20 +224,62 @@
    "read_only": 0
   }, 
   {
-   "fieldname": "section_break_9", 
+   "depends_on": "", 
+   "fieldname": "section_break_24", 
    "fieldtype": "Section Break", 
    "permlevel": 0, 
-   "read_only": 0
+   "precision": ""
   }, 
   {
-   "depends_on": "", 
-   "fieldname": "project", 
-   "fieldtype": "Link", 
-   "in_list_view": 1, 
-   "label": "Project", 
-   "options": "Project", 
+   "default": "0", 
+   "description": "", 
+   "fieldname": "costing_rate", 
+   "fieldtype": "Currency", 
+   "label": "Costing Rate (per hour)", 
    "permlevel": 0, 
-   "read_only": 0
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "default": "0", 
+   "fieldname": "costing_amount", 
+   "fieldtype": "Currency", 
+   "label": "Costing Amount", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
+   "fieldname": "column_break_25", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "default": "0", 
+   "description": "", 
+   "fieldname": "billing_rate", 
+   "fieldtype": "Currency", 
+   "label": "Billing Rate (per hour)", 
+   "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.", 
@@ -214,12 +300,6 @@
    "read_only": 1
   }, 
   {
-   "fieldname": "column_break_16", 
-   "fieldtype": "Column Break", 
-   "permlevel": 0, 
-   "read_only": 0
-  }, 
-  {
    "fieldname": "amended_from", 
    "fieldtype": "Link", 
    "ignore_user_permissions": 1, 
@@ -242,7 +322,7 @@
  "icon": "icon-time", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-04-06 02:47:16.187046", 
+ "modified": "2015-04-14 09:07:28.468792", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Time Log", 
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index c385c09..f7b501d 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -24,12 +24,16 @@
 		self.check_workstation_timings()
 		self.validate_production_order()
 		self.validate_manufacturing()
+		self.validate_task()
+		self.update_cost()
 
 	def on_submit(self):
 		self.update_production_order()
+		self.update_task()
 
 	def on_cancel(self):
 		self.update_production_order()
+		self.update_task()
 
 	def before_update_after_submit(self):
 		self.set_status()
@@ -63,6 +67,7 @@
 	def validate_overlap(self):
 		"""Checks if 'Time Log' entries overlap for a user, workstation. """
 		self.validate_overlap_for("user")
+		self.validate_overlap_for("employee")
 		self.validate_overlap_for("workstation")
 
 	def validate_overlap_for(self, fieldname):
@@ -123,8 +128,8 @@
 
 	def update_production_order(self):
 		"""Updates `start_date`, `end_date`, `status` for operation in Production Order."""
-
-		if self.for_manufacturing and self.production_order:
+		
+		if self.production_order and self.for_manufacturing:
 			if not self.operation_id:
 				frappe.throw(_("Operation ID not set"))
 
@@ -205,6 +210,27 @@
 			self.production_order = None
 			self.operation = None
 			self.quantity = None
+	
+	def update_cost(self):
+		rate = get_activity_cost(self.employee, self.activity_type)
+		if rate:
+			self.costing_rate = rate.get('costing_rate')
+			self.billing_rate = rate.get('billing_rate') 
+			self.costing_amount = self.costing_rate * self.hours
+			if self.billable:
+				self.billing_amount = self.billing_rate * self.hours
+			else:
+				self.billing_amount = 0
+				
+	def validate_task(self):
+		if self.project and not self.task:
+			frappe.throw(_("Task is Mandatory if Time Log is against a project"))
+	
+	def update_task(self):
+		if self.task and frappe.db.exists("Task", self.task):
+			task = frappe.get_doc("Task", self.task)
+			task.update_time_and_costing()
+			task.save()
 
 @frappe.whitelist()
 def get_events(start, end, filters=None):
@@ -242,3 +268,9 @@
 			d.title += " for Project: " + d.project
 
 	return data
+	
+@frappe.whitelist()
+def get_activity_cost(employee=None, activity_type=None):
+	rate = frappe.db.sql("""select costing_rate, billing_rate from `tabActivity Cost` where employee= %s
+		and activity_type= %s""", (employee, activity_type), as_dict=1)
+	return rate[0] if rate else {}
diff --git a/erpnext/projects/doctype/time_log/time_log_list.js b/erpnext/projects/doctype/time_log/time_log_list.js
index d444806..a2eb05c 100644
--- a/erpnext/projects/doctype/time_log/time_log_list.js
+++ b/erpnext/projects/doctype/time_log/time_log_list.js
@@ -3,7 +3,7 @@
 
 // render
 frappe.listview_settings['Time Log'] = {
-	add_fields: ["status", "billable", "activity_type", "task", "project", "hours", "for_manufacturing"],
+	add_fields: ["status", "billable", "activity_type", "task", "project", "hours", "for_manufacturing", "billing_amount"],
 	selectable: true,
 	onload: function(me) {
 		me.page.add_menu_item(__("Make Time Log Batch"), function() {
@@ -37,7 +37,7 @@
 					$.extend(detail, {
 						"time_log": d.name,
 						"activity_type": d.activity_type,
-						"created_by": d.owner,
+						"billing_amount": d.billing_amount,
 						"hours": d.hours
 					});
 				})
diff --git a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
index 240ca97..faa0a60 100644
--- a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
+++ b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
@@ -44,7 +44,6 @@
 def create_time_log_batch(time_log):
 	tlb = frappe.get_doc({
 		"doctype": "Time Log Batch",
-		"rate": "500",
 		"time_logs": [
 			{
 			"doctype": "Time Log Batch Detail",
diff --git a/erpnext/projects/doctype/time_log_batch/time_log_batch.js b/erpnext/projects/doctype/time_log_batch/time_log_batch.js
index 0635db0..6b5f080 100644
--- a/erpnext/projects/doctype/time_log_batch/time_log_batch.js
+++ b/erpnext/projects/doctype/time_log_batch/time_log_batch.js
@@ -2,7 +2,7 @@
 // License: GNU General Public License v3. See license.txt
 
 cur_frm.add_fetch("time_log", "activity_type", "activity_type");
-cur_frm.add_fetch("time_log", "owner", "created_by");
+cur_frm.add_fetch("time_log", "billing_amount", "billing_amount");
 cur_frm.add_fetch("time_log", "hours", "hours");
 
 cur_frm.set_query("time_log", "time_logs", function(doc) {
@@ -36,3 +36,15 @@
 		});
 	}
 });
+
+frappe.ui.form.on("Time Log Batch Detail", "time_log", function(frm, cdt, cdn) {
+	var tl = frm.doc.time_logs || [];
+	total_hr = 0;
+	total_amt = 0;
+	for(var i=0; i<tl.length; i++) {
+		total_hr += tl[i].hours;
+		total_amt += tl[i].billing_amount;
+	}
+	cur_frm.set_value("total_hours", total_hr);
+	cur_frm.set_value("total_billing_amount", total_amt);
+});
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log_batch/time_log_batch.json b/erpnext/projects/doctype/time_log_batch/time_log_batch.json
index a42c4ea..93726ee 100644
--- a/erpnext/projects/doctype/time_log_batch/time_log_batch.json
+++ b/erpnext/projects/doctype/time_log_batch/time_log_batch.json
@@ -15,28 +15,22 @@
    "reqd": 1
   }, 
   {
-   "description": "For Sales Invoice", 
-   "fieldname": "rate", 
-   "fieldtype": "Currency", 
-   "label": "Rate", 
-   "permlevel": 0
-  }, 
-  {
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "permlevel": 0
-  }, 
-  {
    "default": "Draft", 
    "fieldname": "status", 
    "fieldtype": "Select", 
    "in_list_view": 0, 
    "label": "Status", 
+   "no_copy": 1, 
    "options": "Draft\nSubmitted\nBilled\nCancelled", 
    "permlevel": 0, 
    "read_only": 1
   }, 
   {
+   "fieldname": "column_break_3", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0
+  }, 
+  {
    "description": "Will be updated after Sales Invoice is Submitted.", 
    "fieldname": "sales_invoice", 
    "fieldtype": "Link", 
@@ -60,7 +54,14 @@
    "reqd": 1
   }, 
   {
-   "description": "In Hours", 
+   "fieldname": "section_break_8", 
+   "fieldtype": "Section Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "default": "0", 
+   "description": "updated via Time Logs", 
    "fieldname": "total_hours", 
    "fieldtype": "Float", 
    "in_list_view": 1, 
@@ -69,6 +70,22 @@
    "read_only": 1
   }, 
   {
+   "fieldname": "column_break_10", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
+   "default": "0", 
+   "description": "updated via Time Logs", 
+   "fieldname": "total_billing_amount", 
+   "fieldtype": "Float", 
+   "label": "Total Billing Amount", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
+  }, 
+  {
    "fieldname": "amended_from", 
    "fieldtype": "Link", 
    "ignore_user_permissions": 1, 
@@ -83,7 +100,7 @@
  "icon": "icon-time", 
  "idx": 1, 
  "is_submittable": 1, 
- "modified": "2015-02-05 05:11:48.360822", 
+ "modified": "2015-04-15 08:00:52.746961", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Time Log Batch", 
diff --git a/erpnext/projects/doctype/time_log_batch/time_log_batch.py b/erpnext/projects/doctype/time_log_batch/time_log_batch.py
index 9565536..eaccc8c 100644
--- a/erpnext/projects/doctype/time_log_batch/time_log_batch.py
+++ b/erpnext/projects/doctype/time_log_batch/time_log_batch.py
@@ -7,6 +7,7 @@
 import frappe
 from frappe import _
 
+from frappe.utils import flt
 from frappe.model.document import Document
 from frappe.model.mapper import get_mapped_doc
 
@@ -14,22 +15,24 @@
 
 	def validate(self):
 		self.set_status()
-		self.total_hours = 0.0
 		for d in self.get("time_logs"):
 			tl = frappe.get_doc("Time Log", d.time_log)
 			self.update_time_log_values(d, tl)
 			self.validate_time_log_is_submitted(tl)
-			self.total_hours += float(tl.hours or 0.0)
+			self.total_hours += flt(tl.hours)
+			self.total_billing_amount += flt(tl.billing_amount)
 
 	def update_time_log_values(self, d, tl):
 		d.update({
 			"hours": tl.hours,
 			"activity_type": tl.activity_type,
-			"created_by": tl.owner
+			"billing_amount": tl.billing_amount
 		})
 
 	def validate_time_log_is_submitted(self, tl):
-		if tl.status != "Submitted" and self.docstatus == 0:
+		if tl.status == "Batched for Billing":
+			frappe.throw(_("Time Log {0} already billed").format(tl.name))
+		elif tl.status != "Submitted":
 			frappe.throw(_("Time Log {0} must be 'Submitted'").format(tl.name))
 
 	def set_status(self):
@@ -65,15 +68,15 @@
 	def update_item(source_doc, target_doc, source_parent):
 		target_doc.stock_uom = "Hour"
 		target_doc.description = "via Time Logs"
+		target_doc.qty = 1
 
 	target = frappe.new_doc("Sales Invoice")
 	target.append("items", get_mapped_doc("Time Log Batch", source_name, {
 		"Time Log Batch": {
 			"doctype": "Sales Invoice Item",
 			"field_map": {
-				"rate": "base_rate",
-				"name": "time_log_batch",
-				"total_hours": "qty",
+				"total_billing_amount": "rate",
+				"name": "time_log_batch"
 			},
 			"postprocess": update_item
 		}
diff --git a/erpnext/projects/doctype/time_log_batch/time_log_batch_list.js b/erpnext/projects/doctype/time_log_batch/time_log_batch_list.js
index f4876b8..9c02ac3 100644
--- a/erpnext/projects/doctype/time_log_batch/time_log_batch_list.js
+++ b/erpnext/projects/doctype/time_log_batch/time_log_batch_list.js
@@ -1,5 +1,5 @@
 frappe.listview_settings['Time Log Batch'] = {
-	add_fields: ["status", "total_hours", "rate"],
+	add_fields: ["status", "total_hours"],
 	get_indicator: function(doc) {
 		return [__(doc.status), frappe.utils.guess_colour(doc.status), "status,=," + doc.status];
 	}
diff --git a/erpnext/projects/doctype/time_log_batch_detail/time_log_batch_detail.json b/erpnext/projects/doctype/time_log_batch_detail/time_log_batch_detail.json
index 15e7e8e..da8ff4c 100644
--- a/erpnext/projects/doctype/time_log_batch_detail/time_log_batch_detail.json
+++ b/erpnext/projects/doctype/time_log_batch_detail/time_log_batch_detail.json
@@ -1,5 +1,5 @@
 {
- "creation": "2013-03-05 09:11:06.000000", 
+ "creation": "2013-03-05 09:11:06", 
  "docstatus": 0, 
  "doctype": "DocType", 
  "fields": [
@@ -15,15 +15,20 @@
    "width": "200px"
   }, 
   {
-   "fieldname": "created_by", 
-   "fieldtype": "Link", 
+   "fieldname": "hours", 
+   "fieldtype": "Float", 
    "in_list_view": 1, 
-   "label": "Created By", 
-   "options": "User", 
+   "label": "Hours", 
    "permlevel": 0, 
    "read_only": 1
   }, 
   {
+   "fieldname": "section_break_3", 
+   "fieldtype": "Column Break", 
+   "permlevel": 0, 
+   "precision": ""
+  }, 
+  {
    "fieldname": "activity_type", 
    "fieldtype": "Data", 
    "in_list_view": 1, 
@@ -32,18 +37,21 @@
    "read_only": 1
   }, 
   {
-   "fieldname": "hours", 
+   "fieldname": "billing_amount", 
    "fieldtype": "Float", 
    "in_list_view": 1, 
-   "label": "Hours", 
-   "permlevel": 0
+   "label": "Billing Amount", 
+   "permlevel": 0, 
+   "precision": "", 
+   "read_only": 1
   }
  ], 
  "idx": 1, 
  "istable": 1, 
- "modified": "2013-12-20 19:21:54.000000", 
+ "modified": "2015-04-15 05:35:08.805589", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Time Log Batch Detail", 
- "owner": "Administrator"
+ "owner": "Administrator", 
+ "permissions": []
 }
\ No newline at end of file
diff --git a/erpnext/projects/report/project_wise_stock_tracking/project_wise_stock_tracking.py b/erpnext/projects/report/project_wise_stock_tracking/project_wise_stock_tracking.py
index 1ef760e..5800156 100644
--- a/erpnext/projects/report/project_wise_stock_tracking/project_wise_stock_tracking.py
+++ b/erpnext/projects/report/project_wise_stock_tracking/project_wise_stock_tracking.py
@@ -17,8 +17,8 @@
 		data.append([project.name, pr_item_map.get(project.name, 0),
 			se_item_map.get(project.name, 0), dn_item_map.get(project.name, 0),
 			project.project_name, project.status, project.company,
-			project.customer, project.project_value, project.project_start_date,
-			project.completion_date])
+			project.customer, project.estimated_costing, project.expected_start_date,
+			project.expected_end_date])
 
 	return columns, data
 
@@ -30,8 +30,8 @@
 		_("Project Start Date") + ":Date:120", _("Completion Date") + ":Date:120"]
 
 def get_project_details():
-	return frappe.db.sql(""" select name, project_name, status, company, customer, project_value,
-		project_start_date, completion_date from tabProject where docstatus < 2""", as_dict=1)
+	return frappe.db.sql(""" select name, project_name, status, company, customer, estimated_costing,
+		expected_start_date, expected_end_date from tabProject where docstatus < 2""", as_dict=1)
 
 def get_purchased_items_cost():
 	pr_items = frappe.db.sql("""select project_name, sum(base_net_amount) as amount