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
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'''
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"""
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 29bd014fc8d..2484586d041 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("""
+ SELECT
+ name
+ from
+ `tab{ref_dt}`
+ where
+ docstatus = 1
+ and base_net_total = 0
+ and name in %(ref_docs)s
+ """.format(ref_dt=ref_dt), {
+ '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:
diff --git a/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py b/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py
index 52b848ed504..ec498837f5e 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] #nosec
+
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