diff --git a/erpnext/selling/doctype/sales_team/sales_team.json b/erpnext/selling/doctype/sales_team/sales_team.json index c77f9f4b2b..04027b2396 100644 --- a/erpnext/selling/doctype/sales_team/sales_team.json +++ b/erpnext/selling/doctype/sales_team/sales_team.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -9,18 +10,24 @@ "doctype": "DocType", "document_type": "Setup", "editable_grid": 1, + "engine": "InnoDB", "fields": [ { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "sales_person", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, - "in_filter": 1, + "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Sales Person", "length": 0, "no_copy": 0, @@ -32,24 +39,31 @@ "print_hide_if_no_value": 0, "print_width": "200px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 1, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "200px" }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "contact_no", "fieldtype": "Data", "hidden": 1, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Contact No.", "length": 0, "no_copy": 0, @@ -60,24 +74,31 @@ "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "allocated_percentage", "fieldtype": "Float", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Contribution (%)", "length": 0, "no_copy": 0, @@ -88,24 +109,31 @@ "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "100px" }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "allocated_amount", "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Contribution to Net Total", "length": 0, "no_copy": 0, @@ -117,24 +145,63 @@ "print_hide_if_no_value": 0, "print_width": "120px", "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0, "width": "120px" }, { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "commission_rate", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Commission Rate", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 1, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "incentives", "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Incentives", "length": 0, "no_copy": 0, @@ -145,24 +212,26 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 1, "image_view": 0, "in_create": 0, - "is_submittable": 0, "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-07-11 03:28:08.421297", + "modified": "2018-09-17 13:03:14.755974", "modified_by": "Administrator", "module": "Selling", "name": "Sales Team", @@ -171,5 +240,8 @@ "quick_entry": 1, "read_only": 0, "read_only_onload": 0, - "track_seen": 0 + "show_name_in_global_search": 0, + "track_changes": 1, + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/selling/report/sales_person_commission_summary/__init__.py b/erpnext/selling/report/sales_person_commission_summary/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.js b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.js new file mode 100644 index 0000000000..ba6ee784b9 --- /dev/null +++ b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.js @@ -0,0 +1,54 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Sales Person Commission Summary"] = { + "filters": [ + + { + fieldname: "sales_person", + label: __("Sales Person"), + fieldtype: "Link", + options: "Sales Person" + }, + { + fieldname: "doc_type", + label: __("Document Type"), + fieldtype: "Select", + options: "Sales Order\nDelivery Note\nSales Invoice", + default: "Sales Order" + }, + { + fieldname: "from_date", + label: __("From Date"), + fieldtype: "Date", + default: frappe.defaults.get_user_default("year_start_date"), + }, + { + fieldname:"to_date", + label: __("To Date"), + fieldtype: "Date", + default: frappe.datetime.get_today() + }, + { + fieldname:"company", + label: __("Company"), + fieldtype: "Link", + options: "Company", + default: frappe.defaults.get_user_default("Company") + }, + { + fieldname:"customer", + label: __("Customer"), + fieldtype: "Link", + options: "Customer", + }, + { + fieldname:"territory", + label: __("Territory"), + fieldtype: "Link", + options: "Territory", + }, + + ] +} diff --git a/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.json b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.json new file mode 100644 index 0000000000..d5ad9f13e1 --- /dev/null +++ b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.json @@ -0,0 +1,26 @@ +{ + "add_total_row": 1, + "creation": "2018-09-11 17:49:27.256304", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2018-09-11 17:49:27.256304", + "modified_by": "Administrator", + "module": "Selling", + "name": "Sales Person Commission Summary", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Sales Order", + "report_name": "Sales Person Commission Summary", + "report_type": "Script Report", + "roles": [ + { + "role": "Sales Manager" + }, + { + "role": "Maintenance User" + } + ] +} \ No newline at end of file diff --git a/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py new file mode 100644 index 0000000000..0c84909611 --- /dev/null +++ b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py @@ -0,0 +1,142 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import msgprint, _ +from frappe.utils import flt + + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns(filters) + entries = get_entries(filters) + data = [] + + for d in entries: + data.append([ + d.name, d.customer, d.territory, d.posting_date, + d.base_net_amount, d.sales_person, d.allocated_percentage, d.commission_rate, d.allocated_amount,d.incentives + ]) + + if data: + total_row = [""]*len(data[0]) + data.append(total_row) + + return columns, data + +def get_columns(filters): + if not filters.get("doc_type"): + msgprint(_("Please select the document type first"), raise_exception=1) + + columns =[ + { + "label": _(filters["doc_type"]), + "options": filters["doc_type"], + "fieldname": filters['doc_type'], + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Customer"), + "options": "Customer", + "fieldname": "customer", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Territory"), + "options": "Territory", + "fieldname": "territory", + "fieldtype": "Link", + "width": 100 + }, + { + "label": _("Posting Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": 100 + }, + { + "label": _("Amount"), + "fieldname": "amount", + "fieldtype": "Currency", + "width": 120 + }, + { + "label": _("Sales Person"), + "options": "Sales Person", + "fieldname": "sales_person", + "fieldtype": "Link", + "width": 140 + }, + { + "label": _("Contribution %"), + "fieldname": "contribution_percentage", + "fieldtype": "Data", + "width": 110 + }, + { + "label": _("Commission Rate %"), + "fieldname": "commission_rate", + "fieldtype": "Data", + "width": 100 + }, + { + "label": _("Contribution Amount"), + "fieldname": "contribution_amount", + "fieldtype": "Currency", + "width": 120 + }, + { + "label": _("Incentives"), + "fieldname": "incentives", + "fieldtype": "Currency", + "width": 120 + } + ] + + return columns + +def get_entries(filters): + date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date" + + conditions, values = get_conditions(filters, date_field) + entries = frappe.db.sql(""" + select + dt.name, dt.customer, dt.territory, dt.%s as posting_date,dt.base_net_total as base_net_amount, + st.commission_rate,st.sales_person, st.allocated_percentage, st.allocated_amount, st.incentives + from + `tab%s` dt, `tabSales Team` st + where + st.parent = dt.name and st.parenttype = %s + and dt.docstatus = 1 %s order by dt.name desc,st.sales_person + """ %(date_field, filters["doc_type"], '%s', conditions), + tuple([filters["doc_type"]] + values), as_dict=1) + + return entries + +def get_conditions(filters, date_field): + conditions = [""] + values = [] + + for field in ["company", "customer", "territory"]: + if filters.get(field): + conditions.append("dt.{0}=%s".format(field)) + values.append(filters[field]) + + if filters.get("sales_person"): + conditions.append("st.sales_person = '{0}'".format(filters.get("sales_person"))) + + if filters.get("from_date"): + conditions.append("dt.{0}>=%s".format(date_field)) + values.append(filters["from_date"]) + + if filters.get("to_date"): + conditions.append("dt.{0}<=%s".format(date_field)) + values.append(filters["to_date"]) + + return " and ".join(conditions), values + + diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 325f08af42..b7b186a8d6 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -12,6 +12,8 @@ frappe.provide("erpnext.selling"); erpnext.selling.SellingController = erpnext.TransactionController.extend({ setup: function() { this._super(); + this.frm.add_fetch("sales_partner", "commission_rate", "commission_rate"); + this.frm.add_fetch("sales_person", "commission_rate", "commission_rate"); }, onload: function() { @@ -29,8 +31,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ setup_queries: function() { var me = this; - this.frm.add_fetch("sales_partner", "commission_rate", "commission_rate"); - $.each([["customer", "customer"], ["lead", "lead"]], function(i, opts) { @@ -171,17 +171,26 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ allocated_percentage: function(doc, cdt, cdn) { var sales_person = frappe.get_doc(cdt, cdn); - if(sales_person.allocated_percentage) { + sales_person.allocated_percentage = flt(sales_person.allocated_percentage, precision("allocated_percentage", sales_person)); + sales_person.allocated_amount = flt(this.frm.doc.base_net_total * sales_person.allocated_percentage / 100.0, precision("allocated_amount", sales_person)); + refresh_field(["allocated_amount"], sales_person); - refresh_field(["allocated_percentage", "allocated_amount"], sales_person.name, + this.calculate_incentive(sales_person); + refresh_field(["allocated_percentage", "allocated_amount", "commission_rate","incentives"], sales_person.name, sales_person.parentfield); - } + } + }, + + sales_person: function(doc, cdt, cdn) { + var row = frappe.get_doc(cdt, cdn); + this.calculate_incentive(row); + refresh_field("incentives",row.name,row.parentfield); }, warehouse: function(doc, cdt, cdn) { @@ -250,6 +259,15 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ }); }, + calculate_incentive: function(row) { + if(row.allocated_amount) + { + row.incentives = flt( + row.allocated_amount * row.commission_rate / 100.0, + precision("incentives", sales_person)); + } + }, + batch_no: function(doc, cdt, cdn) { var me = this; var item = frappe.get_doc(cdt, cdn); diff --git a/erpnext/setup/doctype/sales_person/sales_person.js b/erpnext/setup/doctype/sales_person/sales_person.js index 2388739b7f..584f879431 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.js +++ b/erpnext/setup/doctype/sales_person/sales_person.js @@ -1,6 +1,15 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt +frappe.ui.form.on('Sales Person', { + refresh: function(frm) { + if(frm.doc.__onload && frm.doc.__onload.dashboard_info) { + var info = frm.doc.__onload.dashboard_info; + frm.dashboard.add_indicator(__('Total Contribution Amount: {0}', + [format_currency(info.allocated_amount, info.currency)]), 'blue'); + } + } +}); cur_frm.cscript.refresh = function(doc, cdt, cdn) { cur_frm.cscript.set_root_readonly(doc); diff --git a/erpnext/setup/doctype/sales_person/sales_person.json b/erpnext/setup/doctype/sales_person/sales_person.json index 715d8dad47..7eeb500f2a 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.json +++ b/erpnext/setup/doctype/sales_person/sales_person.json @@ -1,6 +1,6 @@ { "allow_copy": 0, - "allow_guest_to_view": 0, + "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, "autoname": "field:sales_person_name", @@ -15,7 +15,8 @@ "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -42,11 +43,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -74,11 +76,12 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "translatable": 0, - "unique": 0 + "translatable": 0, + "unique": 1 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -108,11 +111,44 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "commission_rate", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Commission Rate", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -141,47 +177,49 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "default": "1", - "fieldname": "enabled", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Enabled", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "default": "1", + "fieldname": "enabled", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Enabled", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, "fieldname": "cb0", "fieldtype": "Column Break", "hidden": 0, @@ -202,11 +240,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -233,18 +272,19 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fetch_from": "employee.department", - "fieldname": "department", - "fieldtype": "Link", + "fetch_from": "employee.department", + "fieldname": "department", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -252,25 +292,26 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Department", + "label": "Department", "length": 0, "no_copy": 0, - "options": "Department", + "options": "Department", "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -298,11 +339,12 @@ "reqd": 0, "search_index": 1, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -330,11 +372,12 @@ "reqd": 0, "search_index": 1, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -362,11 +405,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -395,11 +439,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -428,11 +473,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 }, { - "allow_bulk_edit": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -462,11 +508,11 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, - "translatable": 0, + "translatable": 0, "unique": 0 } ], - "has_web_view": 0, + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "icon-user", @@ -477,7 +523,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-05-17 09:44:18.203325", + "modified": "2018-09-12 16:41:06.378899", "modified_by": "Administrator", "module": "Setup", "name": "Sales Person", @@ -541,12 +587,13 @@ "write": 1 } ], - "quick_entry": 0, + "quick_entry": 1, "read_only": 0, "read_only_onload": 0, "search_fields": "parent_sales_person", "show_name_in_global_search": 1, "sort_order": "ASC", - "track_changes": 0, - "track_seen": 0 + "track_changes": 1, + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/setup/doctype/sales_person/sales_person.py b/erpnext/setup/doctype/sales_person/sales_person.py index 816ee842e3..ab65f7455e 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.py +++ b/erpnext/setup/doctype/sales_person/sales_person.py @@ -6,9 +6,10 @@ import frappe from frappe import _ from frappe.utils import flt from frappe.utils.nestedset import NestedSet +from erpnext import get_default_currency class SalesPerson(NestedSet): - nsm_parent_field = 'parent_sales_person'; + nsm_parent_field = 'parent_sales_person' def validate(self): for d in self.get('targets') or []: @@ -16,6 +17,24 @@ class SalesPerson(NestedSet): frappe.throw(_("Either target qty or target amount is mandatory.")) self.validate_employee_id() + def onload(self): + self.load_dashboard_info() + + def load_dashboard_info(self): + company_default_currency = get_default_currency() + + allocated_amount = frappe.db.sql(""" + select sum(allocated_amount) + from `tabSales Team` + where sales_person = %s and docstatus=1 and parenttype = 'Sales Order' + """,(self.sales_person_name)) + + info = {} + info["allocated_amount"] = flt(allocated_amount[0][0]) if allocated_amount else 0 + info["currency"] = company_default_currency + + self.set_onload('dashboard_info', info) + def on_update(self): super(SalesPerson, self).on_update() self.validate_one_root() @@ -35,4 +54,48 @@ class SalesPerson(NestedSet): frappe.throw(_("Another Sales Person {0} exists with the same Employee id").format(sales_person)) def on_doctype_update(): - frappe.db.add_index("Sales Person", ["lft", "rgt"]) \ No newline at end of file + frappe.db.add_index("Sales Person", ["lft", "rgt"]) + +def get_timeline_data(doctype, name): + + out = {} + + out.update(dict(frappe.db.sql('''select + unix_timestamp(dt.transaction_date), count(st.parenttype) + from + `tabSales Order` dt, `tabSales Team` st + where + st.sales_person = %s and st.parent = dt.name and dt.transaction_date > date_sub(curdate(), interval 1 year) + group by dt.transaction_date ''', name))) + + sales_invoice = dict(frappe.db.sql('''select + unix_timestamp(dt.posting_date), count(st.parenttype) + from + `tabSales Invoice` dt, `tabSales Team` st + where + st.sales_person = %s and st.parent = dt.name and dt.posting_date > date_sub(curdate(), interval 1 year) + group by dt.posting_date ''', name)) + + for key in sales_invoice: + if out.get(key): + out[key] += sales_invoice[key] + else: + out[key] = sales_invoice[key] + + delivery_note = dict(frappe.db.sql('''select + unix_timestamp(dt.posting_date), count(st.parenttype) + from + `tabDelivery Note` dt, `tabSales Team` st + where + st.sales_person = %s and st.parent = dt.name and dt.posting_date > date_sub(curdate(), interval 1 year) + group by dt.posting_date ''', name)) + + for key in delivery_note: + if out.get(key): + out[key] += delivery_note[key] + else: + out[key] = delivery_note[key] + + return out + + diff --git a/erpnext/setup/doctype/sales_person/sales_person_dashboard.py b/erpnext/setup/doctype/sales_person/sales_person_dashboard.py new file mode 100644 index 0000000000..42528d8832 --- /dev/null +++ b/erpnext/setup/doctype/sales_person/sales_person_dashboard.py @@ -0,0 +1,14 @@ +from frappe import _ + +def get_data(): + return { + 'heatmap': True, + 'heatmap_message': _('This is based on transactions against this Sales Person. See timeline below for details'), + 'fieldname': 'sales_person', + 'transactions': [ + { + 'label': _('Sales'), + 'items': ['Sales Order', 'Delivery Note', 'Sales Invoice'] + }, + ] + } \ No newline at end of file