2017-04-16 19:32:56 +00:00
|
|
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
|
|
|
# For license information, please see license.txt
|
|
|
|
|
2021-09-02 11:14:59 +00:00
|
|
|
|
2017-04-16 19:32:56 +00:00
|
|
|
import frappe
|
|
|
|
from frappe import _
|
2019-07-03 05:04:31 +00:00
|
|
|
from frappe.utils import flt
|
2017-04-16 19:32:56 +00:00
|
|
|
|
2021-09-02 11:14:59 +00:00
|
|
|
|
2017-04-16 19:32:56 +00:00
|
|
|
def execute(filters=None):
|
|
|
|
columns, data = [], []
|
2019-07-03 05:04:31 +00:00
|
|
|
columns = get_columns("Campaign Name")
|
|
|
|
data = get_lead_data(filters or {}, "Campaign Name")
|
2017-04-16 19:32:56 +00:00
|
|
|
return columns, data
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2019-07-03 05:04:31 +00:00
|
|
|
def get_columns(based_on):
|
2017-04-25 10:35:01 +00:00
|
|
|
return [
|
2019-07-03 05:04:31 +00:00
|
|
|
{"fieldname": frappe.scrub(based_on), "label": _(based_on), "fieldtype": "Data", "width": 150},
|
|
|
|
{"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},
|
2017-04-16 19:32:56 +00:00
|
|
|
]
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
def get_lead_data(filters, based_on):
|
|
|
|
based_on_field = frappe.scrub(based_on)
|
|
|
|
conditions = get_filter_conditions(filters)
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
lead_details = frappe.db.sql(
|
|
|
|
"""
|
|
|
|
select {based_on_field}, name
|
2019-07-03 05:04:31 +00:00
|
|
|
from `tabLead`
|
|
|
|
where {based_on_field} is not null and {based_on_field} != '' {conditions}
|
2017-04-25 10:35:01 +00:00
|
|
|
""".format(
|
|
|
|
based_on_field=based_on_field, conditions=conditions
|
|
|
|
),
|
|
|
|
filters,
|
|
|
|
as_dict=1,
|
|
|
|
)
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
lead_map = frappe._dict()
|
|
|
|
for d in lead_details:
|
|
|
|
lead_map.setdefault(d.get(based_on_field), []).append(d.name)
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
data = []
|
|
|
|
for based_on_value, leads in lead_map.items():
|
2019-07-03 05:04:31 +00:00
|
|
|
row = {based_on_field: based_on_value, "lead_count": len(leads)}
|
|
|
|
row["quot_count"] = get_lead_quotation_count(leads)
|
|
|
|
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
|
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
data.append(row)
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
return data
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
def get_filter_conditions(filters):
|
2017-04-16 19:32:56 +00:00
|
|
|
conditions = ""
|
|
|
|
if filters.from_date:
|
|
|
|
conditions += " and date(creation) >= %(from_date)s"
|
|
|
|
if filters.to_date:
|
|
|
|
conditions += " and date(creation) <= %(to_date)s"
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
return conditions
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
def get_lead_quotation_count(leads):
|
2019-07-03 05:04:31 +00:00
|
|
|
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][
|
2022-03-28 13:22:46 +00:00
|
|
|
0
|
2019-07-03 05:04:31 +00:00
|
|
|
] # nosec
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
def get_lead_opp_count(leads):
|
2019-07-03 05:04:31 +00:00
|
|
|
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]
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
def get_quotation_ordered_count(leads):
|
2019-07-03 05:04:31 +00:00
|
|
|
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]
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2019-07-03 05:04:31 +00:00
|
|
|
|
2017-04-25 10:35:01 +00:00
|
|
|
def get_order_amount(leads):
|
2019-07-03 05:04:31 +00:00
|
|
|
return frappe.db.sql(
|
|
|
|
"""select sum(base_net_amount)
|
2017-04-25 10:35:01 +00:00
|
|
|
from `tabSales Order Item`
|
|
|
|
where prevdoc_docname in (
|
2019-07-03 05:04:31 +00:00
|
|
|
select name from `tabQuotation` where status = 'Ordered'
|
|
|
|
and quotation_to = 'Lead' and party_name in (%s)
|
2017-04-25 10:35:01 +00:00
|
|
|
)"""
|
|
|
|
% ", ".join(["%s"] * len(leads)),
|
|
|
|
tuple(leads),
|
|
|
|
)[0][0]
|