From c5a682e9d95292d067c783866e4579f6f1a9ba3f Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Tue, 28 May 2019 23:40:05 +0530 Subject: [PATCH 1/7] fix: Lead owner efficiency report query and column fixes --- .../campaign_efficiency.py | 54 +++++++-------- .../lead_owner_efficiency.py | 65 ++++++++++++++++--- 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py b/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py index 52b848ed504..4451579327a 100644 --- a/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py +++ b/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py @@ -11,7 +11,7 @@ def execute(filters=None): columns=get_columns("Campaign Name") data=get_lead_data(filters or {}, "Campaign Name") return columns, data - + def get_columns(based_on): return [ { @@ -69,21 +69,21 @@ def get_columns(based_on): "width": 100 } ] - + def get_lead_data(filters, based_on): based_on_field = frappe.scrub(based_on) conditions = get_filter_conditions(filters) - + lead_details = frappe.db.sql(""" select {based_on_field}, name - from `tabLead` - where {based_on_field} is not null and {based_on_field} != '' {conditions} + from `tabLead` + where {based_on_field} is not null and {based_on_field} != '' {conditions} """.format(based_on_field=based_on_field, conditions=conditions), filters, as_dict=1) - + lead_map = frappe._dict() for d in lead_details: lead_map.setdefault(d.get(based_on_field), []).append(d.name) - + data = [] for based_on_value, leads in lead_map.items(): row = { @@ -94,42 +94,42 @@ def get_lead_data(filters, based_on): row["opp_count"] = get_lead_opp_count(leads) row["order_count"] = get_quotation_ordered_count(leads) row["order_value"] = get_order_amount(leads) or 0 - + row["opp_lead"] = flt(row["opp_count"]) / flt(row["lead_count"] or 1.0) * 100.0 row["quot_lead"] = flt(row["quot_count"]) / flt(row["lead_count"] or 1.0) * 100.0 - + row["order_quot"] = flt(row["order_count"]) / flt(row["quot_count"] or 1.0) * 100.0 - + data.append(row) - + return data - + def get_filter_conditions(filters): conditions="" if filters.from_date: conditions += " and date(creation) >= %(from_date)s" if filters.to_date: conditions += " and date(creation) <= %(to_date)s" - + return conditions - + def get_lead_quotation_count(leads): - return frappe.db.sql("""select count(name) from `tabQuotation` - where lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] - + return frappe.db.sql("""select count(name) from `tabQuotation` + where quotation_to = 'Lead' and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] + def get_lead_opp_count(leads): - return frappe.db.sql("""select count(name) from `tabOpportunity` - where lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] - + return frappe.db.sql("""select count(name) from `tabOpportunity` + where opportunity_from = 'Lead' and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] + def get_quotation_ordered_count(leads): - return frappe.db.sql("""select count(name) - from `tabQuotation` where status = 'Ordered' - and lead in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] - + return frappe.db.sql("""select count(name) + from `tabQuotation` where status = 'Ordered' and quotation_to = 'Lead' + and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] + def get_order_amount(leads): - return frappe.db.sql("""select sum(base_net_amount) + return frappe.db.sql("""select sum(base_net_amount) from `tabSales Order Item` where prevdoc_docname in ( - select name from `tabQuotation` where status = 'Ordered' - and lead in (%s) + select name from `tabQuotation` where status = 'Ordered' + and quotation_to = 'Lead' and party_name in (%s) )""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] \ No newline at end of file diff --git a/erpnext/crm/report/lead_owner_efficiency/lead_owner_efficiency.py b/erpnext/crm/report/lead_owner_efficiency/lead_owner_efficiency.py index 8134bc20032..6172a75fdd8 100644 --- a/erpnext/crm/report/lead_owner_efficiency/lead_owner_efficiency.py +++ b/erpnext/crm/report/lead_owner_efficiency/lead_owner_efficiency.py @@ -11,16 +11,61 @@ def execute(filters=None): columns=get_columns() data=get_lead_data(filters, "Lead Owner") return columns, data - + def get_columns(): return [ - _("Lead Owner") + ":Data:130", - _("Lead Count") + ":Int:80", - _("Opp Count") + ":Int:80", - _("Quot Count") + ":Int:80", - _("Order Count") + ":Int:100", - _("Order Value") + ":Float:100", - _("Opp/Lead %") + ":Float:100", - _("Quot/Lead %") + ":Float:100", - _("Order/Quot %") + ":Float:100" + { + "fieldname": "lead_owner", + "label": _("Lead Owner"), + "fieldtype": "Data", + "width": "130" + }, + { + "fieldname": "lead_count", + "label": _("Lead Count"), + "fieldtype": "Int", + "width": "80" + }, + { + "fieldname": "opp_count", + "label": _("Opp Count"), + "fieldtype": "Int", + "width": "80" + }, + { + "fieldname": "quot_count", + "label": _("Quot Count"), + "fieldtype": "Int", + "width": "80" + }, + { + "fieldname": "order_count", + "label": _("Order Count"), + "fieldtype": "Int", + "width": "100" + }, + { + "fieldname": "order_value", + "label": _("Order Value"), + "fieldtype": "Float", + "width": "100" + }, + { + "fieldname": "opp_lead", + "label": _("Opp/Lead %"), + "fieldtype": "Float", + "width": "100" + }, + { + "fieldname": "quot_lead", + "label": _("Quot/Lead %"), + "fieldtype": "Float", + "width": "100" + }, + { + "fieldname": "order_quot", + "label": _("Order/Quot %"), + "fieldtype": "Float", + "width": "100" + } ] \ No newline at end of file From 7b6ed4f16e7c572495c1c15388cfd6f5308ee57a Mon Sep 17 00:00:00 2001 From: Himanshu Mishra Date: Tue, 28 May 2019 23:51:22 +0530 Subject: [PATCH 2/7] Update status_updater.py --- erpnext/controllers/status_updater.py | 30 +++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index 29bd014fc8d..204e7c3fc90 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -316,19 +316,27 @@ class StatusUpdater(Document): .format(frappe.db.escape(frappe.session.user)) def update_billing_status_for_zero_amount_refdoc(self, ref_dt): - ref_fieldname = ref_dt.lower().replace(" ", "_") - zero_amount_refdoc = [] - all_zero_amount_refdoc = frappe.db.sql_list("""select name from `tab%s` - where docstatus=1 and base_net_total = 0""" % ref_dt) + ref_fieldname = frappe.scrub(ref_dt) - for item in self.get("items"): - if item.get(ref_fieldname) \ - and item.get(ref_fieldname) in all_zero_amount_refdoc \ - and item.get(ref_fieldname) not in zero_amount_refdoc: - zero_amount_refdoc.append(item.get(ref_fieldname)) + ref_docs = [item.get(ref_fieldname) for item in (self.get('items') or []) if item.get(ref_fieldname)] + if not ref_docs: + return - if zero_amount_refdoc: - self.update_billing_status(zero_amount_refdoc, ref_dt, ref_fieldname) + zero_amount_refdocs = frappe.db.sql_list(f""" + SELECT + name + from + `tab{ref_dt}` + where + docstatus = 1 + and base_net_total = 0 + and name in %(ref_docs)s + """, { + 'ref_docs': ref_docs + }) + + if zero_amount_refdocs: + self.update_billing_status(zero_amount_refdocs, ref_dt, ref_fieldname) def update_billing_status(self, zero_amount_refdoc, ref_dt, ref_fieldname): for ref_dn in zero_amount_refdoc: From d355741462f61fd85999643a8c88bbec109c0dce Mon Sep 17 00:00:00 2001 From: Himanshu Mishra Date: Tue, 28 May 2019 23:54:03 +0530 Subject: [PATCH 3/7] Python 2 compatibility -_- --- erpnext/controllers/status_updater.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index 204e7c3fc90..2484586d041 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -322,7 +322,7 @@ class StatusUpdater(Document): if not ref_docs: return - zero_amount_refdocs = frappe.db.sql_list(f""" + zero_amount_refdocs = frappe.db.sql_list(""" SELECT name from @@ -331,7 +331,7 @@ class StatusUpdater(Document): docstatus = 1 and base_net_total = 0 and name in %(ref_docs)s - """, { + """.format(ref_dt=ref_dt), { 'ref_docs': ref_docs }) From 217df1761db35493bfc99810560da24d673156fe Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Wed, 29 May 2019 08:10:07 +0530 Subject: [PATCH 4/7] fix: Styling fixes --- erpnext/crm/report/campaign_efficiency/campaign_efficiency.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py b/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py index 4451579327a..ec498837f5e 100644 --- a/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py +++ b/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py @@ -115,7 +115,7 @@ def get_filter_conditions(filters): def get_lead_quotation_count(leads): return frappe.db.sql("""select count(name) from `tabQuotation` - where quotation_to = 'Lead' and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] + where quotation_to = 'Lead' and party_name in (%s)""" % ', '.join(["%s"]*len(leads)), tuple(leads))[0][0] #nosec def get_lead_opp_count(leads): return frappe.db.sql("""select count(name) from `tabOpportunity` From f296a2f58aafdcf5db3f2b3b26505531c0d0ec89 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 29 May 2019 15:14:07 +0530 Subject: [PATCH 5/7] perf: Remove MANIFEST.in Faster pip install -e erpnext https://stackoverflow.com/questions/24727709/do-python-projects-need-a-manifest-in-and-what-should-be-in-it https://github.com/frappe/frappe/pull/7360 --- MANIFEST.in | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 3e467e53621..00000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,20 +0,0 @@ -include MANIFEST.in -include requirements.txt -include *.json -include *.md -include *.py -include *.txt -include .travis.yml -recursive-include erpnext *.txt -recursive-include erpnext *.css -recursive-include erpnext *.csv -recursive-include erpnext *.html -recursive-include erpnext *.ico -recursive-include erpnext *.js -recursive-include erpnext *.json -recursive-include erpnext *.md -recursive-include erpnext *.png -recursive-include erpnext *.py -recursive-include erpnext *.svg -recursive-include erpnext/public * -recursive-exclude * *.pyc From cfecf3c5b104d3de70710c49c42aae5718d35beb Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Wed, 29 May 2019 17:16:48 +0530 Subject: [PATCH 6/7] fix: Added description if item variants does not have description in map (#17795) * fix: variant item description based on attribute * fix: requested changes * fix: refactor --- erpnext/controllers/item_variant.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py index 31ae83a0ce2..4230d17ff0e 100644 --- a/erpnext/controllers/item_variant.py +++ b/erpnext/controllers/item_variant.py @@ -288,14 +288,18 @@ def copy_attributes_to_variant(item, variant): variant.variant_of = item.name - if not variant.description: - variant.description = "" - if 'description' not in allow_fields: - if item.variant_based_on == 'Item Attribute' and not variant.description: - variant.description = "
" + item.name + "
" - for d in variant.attributes: - variant.description += "
" + d.attribute + ": " + cstr(d.attribute_value) + "
" + if not variant.description: + variant.description = "" + + if item.variant_based_on=='Item Attribute': + if variant.attributes: + attributes_description = item.description + " " + for d in variant.attributes: + attributes_description += "
" + d.attribute + ": " + cstr(d.attribute_value) + "
" + + if attributes_description not in variant.description: + variant.description += attributes_description def make_variant_item_code(template_item_code, template_item_name, variant): """Uses template's item code and abbreviations to make variant's item code""" From 08617f770011a88121c042d63f5c585917a5bd84 Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Thu, 30 May 2019 12:29:35 +0550 Subject: [PATCH 7/7] bumped to version 11.1.35 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 90bf6b772ef..69019252479 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '11.1.34' +__version__ = '11.1.35' def get_default_company(user=None): '''Get default company for user'''