Added %billed in timesheet
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 47ebc3d..47f1a5c 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -481,16 +481,22 @@
})
frappe.ui.form.on('Sales Invoice Timesheet', {
- time_sheet: function(frm){
- frm.call({
- method: "calculate_billing_amount_from_timesheet",
- doc: frm.doc,
+ time_sheet: function(frm, cdt, cdn){
+ var d = locals[cdt][cdn];
+ frappe.call({
+ method: "erpnext.projects.doctype.timesheet.timesheet.get_timesheet_data",
+ args: {
+ 'name': d.time_sheet,
+ 'project': frm.doc.project || null
+ },
callback: function(r, rt) {
- refresh_field('total_billing_amount')
+ if(r.message){
+ data = r.message;
+ frappe.model.set_value(cdt, cdn, "billing_hours", data.billing_hours);
+ frappe.model.set_value(cdt, cdn, "billing_amount", data.billing_amount);
+ frappe.model.set_value(cdt, cdn, "timesheet_detail", data.timesheet_detail);
+ }
}
})
}
})
-
-cur_frm.add_fetch("time_sheet", "total_billing_hours", "billing_hours");
-cur_frm.add_fetch("time_sheet", "total_billing_amount", "billing_amount");
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index ffe5237..99b4793 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -342,6 +342,34 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "Project",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "project_name",
+ "oldfieldtype": "Link",
+ "options": "Project",
+ "permlevel": 0,
+ "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,
+ "columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -1082,59 +1110,6 @@
{
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "project_detail",
- "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,
- "columns": 0,
- "fieldname": "project",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "label": "Project",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "project_name",
- "oldfieldtype": "Link",
- "options": "Project",
- "permlevel": 0,
- "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": 1,
"collapsible_depends_on": "eval:doc.total_billing_amount > 0",
"columns": 0,
@@ -3892,7 +3867,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-09-07 03:04:15.927629",
+ "modified": "2016-09-08 09:05:02.895682",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 34296ea..f75a9af 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -222,17 +222,19 @@
for d in self.timesheets:
if d.time_sheet:
timesheet = frappe.get_doc("Timesheet", d.time_sheet)
- self.update_time_sheet_detail(timesheet, d)
- timesheet.sales_invoice = sales_invoice
+ self.update_time_sheet_detail(timesheet, d, sales_invoice)
+ timesheet.calculate_total_amounts()
+ timesheet.calculate_percentage_billed()
timesheet.flags.ignore_validate_update_after_submit = True
timesheet.set_status()
timesheet.save()
- def update_time_sheet_detail(self, timesheet, args):
+ def update_time_sheet_detail(self, timesheet, args, sales_invoice):
for data in timesheet.time_logs:
- if (self.project and self.project == data.project) or \
- (not self.project and (data.billing_amount - data.billed_amount) > 0):
- data.billed_amount = args.billing_amount
+ if (self.project and args.timesheet_detail == data.name) or \
+ (not self.project and not data.sales_invoice) or \
+ (not sales_invoice and data.sales_invoice == self.name):
+ data.sales_invoice = sales_invoice
if self.project: return
def on_update(self):
@@ -480,7 +482,8 @@
self.append('timesheets', {
'time_sheet': data.parent,
'billing_hours': data.billing_hours,
- 'billing_amount': data.billing_amt
+ 'billing_amount': data.billing_amt,
+ 'timesheet_detail': data.name
})
self.calculate_billing_amount_from_timesheet()
diff --git a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
index 25dd3cb..e34acca 100644
--- a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
+++ b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
@@ -14,6 +14,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "time_sheet",
"fieldtype": "Link",
"hidden": 0,
@@ -40,6 +41,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "billing_hours",
"fieldtype": "Float",
"hidden": 0,
@@ -65,6 +67,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "billing_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -85,6 +88,32 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "timesheet_detail",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Timesheet Detail",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
}
],
"hide_heading": 0,
@@ -97,7 +126,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-08-22 21:32:55.504103",
+ "modified": "2016-09-08 05:36:00.922319",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Timesheet",
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 42fe005..a47b4ac 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -31,7 +31,7 @@
refresh: function(frm) {
if(frm.doc.docstatus==1) {
- if(!frm.doc.sales_invoice && frm.doc.total_billing_amount > 0){
+ if(frm.doc.per_billed < 100){
frm.add_custom_button(__("Make Sales Invoice"), function() { frm.trigger("make_invoice") },
"icon-file-alt");
}
@@ -42,7 +42,7 @@
}
}
- if(frm.doc.sales_invoice) {
+ if(frm.doc.per_billed > 0) {
cur_frm.fields_dict["time_logs"].grid.toggle_enable("billing_hours", false);
}
},
diff --git a/erpnext/projects/doctype/timesheet/timesheet.json b/erpnext/projects/doctype/timesheet/timesheet.json
index 1c174c8..caa3e7e 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.json
+++ b/erpnext/projects/doctype/timesheet/timesheet.json
@@ -571,23 +571,49 @@
"unique": 0
},
{
- "allow_on_submit": 1,
+ "allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "total_billed_amount",
+ "fieldname": "total_billed_hours",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Total Billed Amount",
+ "label": "Total Billed Hours",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
- "print_hide": 1,
+ "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,
+ "columns": 0,
+ "fieldname": "total_costing_amount",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Total Costing Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
@@ -651,25 +677,51 @@
"unique": 0
},
{
- "allow_on_submit": 0,
+ "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "total_costing_amount",
+ "fieldname": "total_billed_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Total Costing Amount",
+ "label": "Total Billed Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "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,
+ "columns": 0,
+ "fieldname": "per_billed",
+ "fieldtype": "Percent",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "% Amount Billed",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -765,7 +817,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-09-07 06:48:27.316087",
+ "modified": "2016-09-08 06:35:06.943066",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet",
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 68a8f4d..867603b 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -25,10 +25,12 @@
self.validate_time_logs()
self.update_cost()
self.calculate_total_amounts()
+ self.calculate_percentage_billed()
def calculate_total_amounts(self):
self.total_hours = 0.0
self.total_billing_hours = 0.0
+ self.total_billed_hours = 0.0
self.total_billing_amount = 0.0
self.total_costing_amount = 0.0
self.total_billed_amount = 0.0
@@ -37,11 +39,17 @@
self.update_billing_hours(d)
self.total_hours += flt(d.hours)
- self.total_billing_hours += flt(d.billing_hours)
- if d.billable:
+ if d.billable:
+ self.total_billing_hours += flt(d.billing_hours)
self.total_billing_amount += flt(d.billing_amount)
self.total_costing_amount += flt(d.costing_amount)
- self.total_billed_amount += flt(d.billed_amount)
+ self.total_billed_amount += flt(d.billing_amount) if d.sales_invoice else 0.0
+ self.total_billed_hours += flt(d.billing_hours) if d.sales_invoice else 0.0
+
+ def calculate_percentage_billed(self):
+ self.per_billed = 0
+ if self.total_billed_amount > 0 and self.total_billing_amount > 0:
+ self.per_billed = (self.total_billed_amount * 100) / self.total_billing_amount
def update_billing_hours(self, args):
if cint(args.billing_hours) == 0:
@@ -54,7 +62,7 @@
"2": "Cancelled"
}[str(self.docstatus or 0)]
- if self.sales_invoice:
+ if self.per_billed == 100:
self.status = "Billed"
if self.salary_slip:
@@ -253,9 +261,9 @@
if parent:
cond = "and parent = %(parent)s"
- return frappe.db.sql("""select parent, billing_hours, (billing_amount - billed_amount) as billing_amt
+ return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
from `tabTimesheet Detail` where docstatus=1 and project = %(project)s {0}
- having billing_amt > 0""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
+ and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
@frappe.whitelist()
def get_timesheet(doctype, txt, searchfield, start, page_len, filters):
@@ -266,9 +274,10 @@
condition = "and tsd.project = %(project)s"
return frappe.db.sql("""select distinct tsd.parent from `tabTimesheet Detail` tsd,
- `tabTimesheet` ts where ts.status in ('Submitted', 'Payslip') and
- (tsd.billing_amount - tsd.billed_amount) > 0 and
- tsd.docstatus = 1 and tsd.parent LIKE %(txt)s {condition}
+ `tabTimesheet` ts where
+ ts.status in ('Submitted', 'Payslip') and tsd.parent = ts.name and
+ tsd.docstatus = 1 and ts.total_billing_amount > 0
+ and tsd.parent LIKE %(txt)s {condition}
order by tsd.parent limit %(start)s, %(page_len)s"""
.format(condition=condition), {
"txt": "%%%s%%" % frappe.db.escape(txt),
@@ -276,20 +285,30 @@
})
@frappe.whitelist()
+def get_timesheet_data(name, project):
+ if project and project!='':
+ data = get_projectwise_timesheet_data(project, name)
+ else:
+ data = frappe.get_all('Timesheet',
+ fields = ["(total_billing_amount - total_billed_amount) as billing_amt", "total_billing_hours as billing_hours"], filters = {'name': name})
+
+ return {
+ 'billing_hours': data[0].billing_hours,
+ 'billing_amount': data[0].billing_amt,
+ 'timesheet_detail': data[0].name if project and project!= '' else None
+ }
+
+@frappe.whitelist()
def make_sales_invoice(source_name, target=None):
target = frappe.new_doc("Sales Invoice")
+ timesheet = frappe.get_doc('Timesheet', source_name)
- target.append("timesheets", get_mapped_doc("Timesheet", source_name, {
- "Timesheet": {
- "doctype": "Sales Invoice Timesheet",
- "field_map": {
- "total_billing_amount": "billing_amount",
- "total_billing_hours": "billing_hours",
- "name": "time_sheet"
- },
- }
- }))
-
+ target.append('timesheets', {
+ 'time_sheet': timesheet.name,
+ 'billing_hours': flt(timesheet.total_billing_hours) - flt(timesheet.total_billed_hours),
+ 'billing_amount': flt(timesheet.total_billing_amount) - flt(timesheet.total_billed_amount)
+ })
+
target.run_method("calculate_billing_amount_from_timesheet")
return target
@@ -330,7 +349,7 @@
["costing_rate", "billing_rate"], as_dict=True)
return rate[0] if rate else {}
-
+
@frappe.whitelist()
def get_events(start, end, filters=None):
"""Returns events for Gantt / Calendar view rendering.
diff --git a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
index 560ce9f..300fed3 100644
--- a/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
+++ b/erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
@@ -378,33 +378,6 @@
"unique": 0
},
{
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "billed_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Billed Amount",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "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,
@@ -618,6 +591,59 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "reference",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Reference",
+ "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": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sales_invoice",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Sales Invoice",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Sales Invoice",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
}
],
"hide_heading": 0,
@@ -630,7 +656,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-07 02:55:22.545715",
+ "modified": "2016-09-08 03:24:26.221661",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet Detail",