set project wise timesheet data
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 4886dea..47ebc3d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -462,12 +462,21 @@
frappe.ui.form.on('Sales Invoice', {
setup: function(frm){
frm.fields_dict["timesheets"].grid.get_field("time_sheet").get_query = function(doc, cdt, cdn){
- return {
- filters: [
- ["Timesheet", "status", "in", ["Submitted", "Payslip"]]
- ]
+ return{
+ query: "erpnext.projects.doctype.timesheet.timesheet.get_timesheet",
+ filters: {'project': doc.project}
}
}
+ },
+
+ project: function(frm){
+ frm.call({
+ method: "add_timesheet_data",
+ doc: frm.doc,
+ callback: function(r, rt) {
+ refresh_field(['timesheets'])
+ }
+ })
}
})
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index ec72be1..34296ea 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -14,6 +14,7 @@
from erpnext.controllers.selling_controller import SellingController
from erpnext.accounts.utils import get_account_currency
from erpnext.stock.doctype.delivery_note.delivery_note import update_billed_amount_based_on_so
+from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data
from erpnext.accounts.doctype.asset.depreciation \
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
@@ -221,11 +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
timesheet.flags.ignore_validate_update_after_submit = True
timesheet.set_status()
timesheet.save()
+ def update_time_sheet_detail(self, timesheet, args):
+ 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: return
+
def on_update(self):
self.set_paid_amount()
@@ -464,6 +473,18 @@
self.total_billing_amount = total_billing_amount
+ def add_timesheet_data(self):
+ self.set('timesheets', [])
+ if self.project:
+ for data in get_projectwise_timesheet_data(self.project):
+ self.append('timesheets', {
+ 'time_sheet': data.parent,
+ 'billing_hours': data.billing_hours,
+ 'billing_amount': data.billing_amt
+ })
+
+ self.calculate_billing_amount_from_timesheet()
+
def get_warehouse(self):
user_pos_profile = frappe.db.sql("""select name, warehouse from `tabPOS Profile`
where ifnull(user,'') = %s and company = %s""", (frappe.session['user'], self.company))
diff --git a/erpnext/projects/doctype/timesheet/timesheet.json b/erpnext/projects/doctype/timesheet/timesheet.json
index 781fa03..1c174c8 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.json
+++ b/erpnext/projects/doctype/timesheet/timesheet.json
@@ -571,6 +571,32 @@
"unique": 0
},
{
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "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 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,
@@ -739,7 +765,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-09-07 02:54:20.930768",
+ "modified": "2016-09-07 06:48:27.316087",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet",
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 63cb898..68a8f4d 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -31,6 +31,7 @@
self.total_billing_hours = 0.0
self.total_billing_amount = 0.0
self.total_costing_amount = 0.0
+ self.total_billed_amount = 0.0
for d in self.get("time_logs"):
self.update_billing_hours(d)
@@ -40,6 +41,7 @@
if d.billable:
self.total_billing_amount += flt(d.billing_amount)
self.total_costing_amount += flt(d.costing_amount)
+ self.total_billed_amount += flt(d.billed_amount)
def update_billing_hours(self, args):
if cint(args.billing_hours) == 0:
@@ -245,6 +247,34 @@
data.billing_amount = data.billing_rate * hours
data.costing_amount = data.costing_rate * hours
+@frappe.whitelist()
+def get_projectwise_timesheet_data(project, parent=None):
+ cond = ''
+ if parent:
+ cond = "and parent = %(parent)s"
+
+ return frappe.db.sql("""select parent, billing_hours, (billing_amount - billed_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)
+
+@frappe.whitelist()
+def get_timesheet(doctype, txt, searchfield, start, page_len, filters):
+ if not filters: filters = {}
+
+ condition = ""
+ if filters.get("project"):
+ 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}
+ order by tsd.parent limit %(start)s, %(page_len)s"""
+ .format(condition=condition), {
+ "txt": "%%%s%%" % frappe.db.escape(txt),
+ "start": start, "page_len": page_len, 'project': filters.get("project")
+ })
+
@frappe.whitelist()
def make_sales_invoice(source_name, target=None):
target = frappe.new_doc("Sales Invoice")