Set billing hours to 0 in timesheet #9535 (#10139)
* `update_billing_hours` to use flt not cint
* if not billable, reset billable hours
* if not billable, reset time rates
* test
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index 1db0610..955a2b0 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -14,8 +14,8 @@
class TestTimesheet(unittest.TestCase):
def test_timesheet_billing_amount(self):
- salary_structure = make_salary_structure("_T-Employee-0001")
- timesheet = make_timesheet("_T-Employee-0001", simulate = True, billable=1)
+ make_salary_structure("_T-Employee-0001")
+ timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1)
self.assertEquals(timesheet.total_hours, 2)
self.assertEquals(timesheet.total_billable_hours, 2)
@@ -23,6 +23,16 @@
self.assertEquals(timesheet.time_logs[0].billing_amount, 100)
self.assertEquals(timesheet.total_billable_amount, 100)
+ def test_timesheet_billing_amount_not_billable(self):
+ make_salary_structure("_T-Employee-0001")
+ timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=0)
+
+ self.assertEquals(timesheet.total_hours, 2)
+ self.assertEquals(timesheet.total_billable_hours, 0)
+ self.assertEquals(timesheet.time_logs[0].billing_rate, 0)
+ self.assertEquals(timesheet.time_logs[0].billing_amount, 0)
+ self.assertEquals(timesheet.total_billable_amount, 0)
+
def test_salary_slip_from_timesheet(self):
salary_structure = make_salary_structure("_T-Employee-0001")
timesheet = make_timesheet("_T-Employee-0001", simulate = True, billable=1)
@@ -43,7 +53,7 @@
self.assertEquals(timesheet.status, 'Submitted')
def test_sales_invoice_from_timesheet(self):
- timesheet = make_timesheet("_T-Employee-0001", simulate = True, billable = 1)
+ timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1)
sales_invoice = make_sales_invoice(timesheet.name)
sales_invoice.customer = "_Test Customer"
sales_invoice.due_date = nowdate()
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 441ab1a..9b330e7 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -105,7 +105,9 @@
},
billable: function(frm, cdt, cdn) {
- calculate_billing_costing_amount(frm, cdt, cdn)
+ update_billing_hours(frm, cdt, cdn);
+ update_time_rates(frm, cdt, cdn);
+ calculate_billing_costing_amount(frm, cdt, cdn);
},
activity_type: function(frm, cdt, cdn) {
@@ -148,8 +150,21 @@
}
}
+var update_billing_hours = function(frm, cdt, cdn){
+ var child = locals[cdt][cdn];
+ if(!child.billable) frappe.model.set_value(cdt, cdn, 'billing_hours', 0.0);
+}
+
+var update_time_rates = function(frm, cdt, cdn){
+ var child = locals[cdt][cdn];
+ if(!child.billable){
+ frappe.model.set_value(cdt, cdn, 'billing_rate', 0.0);
+ frappe.model.set_value(cdt, cdn, 'costing_rate', 0.0);
+ }
+}
+
var calculate_billing_costing_amount = function(frm, cdt, cdn){
- var child = locals[cdt][cdn]
+ var child = locals[cdt][cdn];
var billing_amount = 0.0;
var costing_amount = 0.0;
@@ -160,7 +175,7 @@
frappe.model.set_value(cdt, cdn, 'billing_amount', billing_amount);
frappe.model.set_value(cdt, cdn, 'costing_amount', costing_amount);
- calculate_time_and_amount(frm)
+ calculate_time_and_amount(frm);
}
var calculate_time_and_amount = function(frm) {
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 6416176..bb3d902 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -46,6 +46,7 @@
for d in self.get("time_logs"):
self.update_billing_hours(d)
+ self.update_time_rates(d)
self.total_hours += flt(d.hours)
if d.billable:
@@ -61,8 +62,11 @@
self.per_billed = (self.total_billed_amount * 100) / self.total_billable_amount
def update_billing_hours(self, args):
- if cint(args.billing_hours) == 0:
- args.billing_hours = args.hours
+ if args.billable:
+ if flt(args.billing_hours) == 0.0:
+ args.billing_hours = args.hours
+ else:
+ args.billing_hours = 0
def set_status(self):
self.status = {
@@ -263,13 +267,19 @@
for data in self.time_logs:
if data.activity_type and data.billable:
rate = get_activity_cost(self.employee, data.activity_type)
- hours = data.billing_hours or 0
+ hours = data.billing_hours or 0
if rate:
data.billing_rate = flt(rate.get('billing_rate')) if flt(data.billing_rate) == 0 else data.billing_rate
data.costing_rate = flt(rate.get('costing_rate')) if flt(data.costing_rate) == 0 else data.costing_rate
data.billing_amount = data.billing_rate * hours
data.costing_amount = data.costing_rate * hours
+ def update_time_rates(self, ts_detail):
+ if not ts_detail.billable:
+ ts_detail.billing_rate = 0.0
+ ts_detail.costing_rate = 0.0
+
+
@frappe.whitelist()
def get_projectwise_timesheet_data(project, parent=None):
cond = ''