mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 17:04:47 +00:00
refactor(treewide): formatting and ruff fixes, + manually enabled F401
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
This commit is contained in:
@@ -178,7 +178,9 @@ class Appointment(Document):
|
||||
"starts_on": self.scheduled_time,
|
||||
"status": "Open",
|
||||
"type": "Public",
|
||||
"send_reminder": frappe.db.get_single_value("Appointment Booking Settings", "email_reminders"),
|
||||
"send_reminder": frappe.db.get_single_value(
|
||||
"Appointment Booking Settings", "email_reminders"
|
||||
),
|
||||
"event_participants": [
|
||||
dict(reference_doctype=self.appointment_with, reference_docname=self.party)
|
||||
],
|
||||
@@ -231,9 +233,7 @@ def _get_agent_list_as_strings():
|
||||
|
||||
|
||||
def _check_agent_availability(agent_email, scheduled_time):
|
||||
appointemnts_at_scheduled_time = frappe.get_all(
|
||||
"Appointment", filters={"scheduled_time": scheduled_time}
|
||||
)
|
||||
appointemnts_at_scheduled_time = frappe.get_all("Appointment", filters={"scheduled_time": scheduled_time})
|
||||
for appointment in appointemnts_at_scheduled_time:
|
||||
if appointment._assign == agent_email:
|
||||
return False
|
||||
|
||||
@@ -19,13 +19,13 @@ class AppointmentBookingSettings(Document):
|
||||
|
||||
def save(self):
|
||||
self.number_of_agents = len(self.agent_list)
|
||||
super(AppointmentBookingSettings, self).save()
|
||||
super().save()
|
||||
|
||||
def validate_availability_of_slots(self):
|
||||
for record in self.availability_of_slots:
|
||||
from_time = datetime.datetime.strptime(self.min_date + record.from_time, self.format_string)
|
||||
to_time = datetime.datetime.strptime(self.min_date + record.to_time, self.format_string)
|
||||
timedelta = to_time - from_time
|
||||
to_time - from_time
|
||||
self.validate_from_and_to_time(from_time, to_time, record)
|
||||
self.duration_is_divisible(from_time, to_time)
|
||||
|
||||
@@ -39,6 +39,4 @@ class AppointmentBookingSettings(Document):
|
||||
def duration_is_divisible(self, from_time, to_time):
|
||||
timedelta = to_time - from_time
|
||||
if timedelta.total_seconds() % (self.appointment_duration * 60):
|
||||
frappe.throw(
|
||||
_("The difference between from time and To Time must be a multiple of Appointment")
|
||||
)
|
||||
frappe.throw(_("The difference between from time and To Time must be a multiple of Appointment"))
|
||||
|
||||
@@ -13,12 +13,12 @@ class Contract(Document):
|
||||
name = self.party_name
|
||||
|
||||
if self.contract_template:
|
||||
name += " - {} Agreement".format(self.contract_template)
|
||||
name += f" - {self.contract_template} Agreement"
|
||||
|
||||
# If identical, append contract name with the next number in the iteration
|
||||
if frappe.db.exists("Contract", name):
|
||||
count = len(frappe.get_all("Contract", filters={"name": ["like", "%{}%".format(name)]}))
|
||||
name = "{} - {}".format(name, count)
|
||||
count = len(frappe.get_all("Contract", filters={"name": ["like", f"%{name}%"]}))
|
||||
name = f"{name} - {count}"
|
||||
|
||||
self.name = _(name)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ from erpnext.selling.doctype.customer.customer import parse_full_name
|
||||
|
||||
class Lead(SellingController, CRMNote):
|
||||
def get_feed(self):
|
||||
return "{0}: {1}".format(_(self.status), self.lead_name)
|
||||
return f"{_(self.status)}: {self.lead_name}"
|
||||
|
||||
def onload(self):
|
||||
customer = frappe.db.get_value("Customer", {"lead_name": self.name})
|
||||
@@ -122,9 +122,7 @@ class Lead(SellingController, CRMNote):
|
||||
self.contact_doc.save()
|
||||
|
||||
def update_prospect(self):
|
||||
lead_row_name = frappe.db.get_value(
|
||||
"Prospect Lead", filters={"lead": self.name}, fieldname="name"
|
||||
)
|
||||
lead_row_name = frappe.db.get_value("Prospect Lead", filters={"lead": self.name}, fieldname="name")
|
||||
if lead_row_name:
|
||||
lead_row = frappe.get_doc("Prospect Lead", lead_row_name)
|
||||
lead_row.update(
|
||||
@@ -174,9 +172,7 @@ class Lead(SellingController, CRMNote):
|
||||
)
|
||||
|
||||
def has_lost_quotation(self):
|
||||
return frappe.db.get_value(
|
||||
"Quotation", {"party_name": self.name, "docstatus": 1, "status": "Lost"}
|
||||
)
|
||||
return frappe.db.get_value("Quotation", {"party_name": self.name, "docstatus": 1, "status": "Lost"})
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_prospect_and_contact(self, data):
|
||||
@@ -448,8 +444,8 @@ def get_lead_with_phone_number(number):
|
||||
leads = frappe.get_all(
|
||||
"Lead",
|
||||
or_filters={
|
||||
"phone": ["like", "%{}".format(number)],
|
||||
"mobile_no": ["like", "%{}".format(number)],
|
||||
"phone": ["like", f"%{number}"],
|
||||
"mobile_no": ["like", f"%{number}"],
|
||||
},
|
||||
limit=1,
|
||||
order_by="creation DESC",
|
||||
@@ -476,9 +472,7 @@ def add_lead_to_prospect(lead, prospect):
|
||||
link_open_events("Lead", lead, prospect)
|
||||
|
||||
frappe.msgprint(
|
||||
_("Lead {0} has been added to prospect {1}.").format(
|
||||
frappe.bold(lead), frappe.bold(prospect.name)
|
||||
),
|
||||
_("Lead {0} has been added to prospect {1}.").format(frappe.bold(lead), frappe.bold(prospect.name)),
|
||||
title=_("Lead -> Prospect"),
|
||||
indicator="green",
|
||||
)
|
||||
|
||||
@@ -134,9 +134,7 @@ class TestLead(unittest.TestCase):
|
||||
self.assertEqual(event.event_participants[1].reference_docname, opportunity.name)
|
||||
|
||||
self.assertTrue(
|
||||
frappe.db.get_value(
|
||||
"ToDo", {"reference_type": "Opportunity", "reference_name": opportunity.name}
|
||||
)
|
||||
frappe.db.get_value("ToDo", {"reference_type": "Opportunity", "reference_name": opportunity.name})
|
||||
)
|
||||
|
||||
def test_copy_events_from_lead_to_prospect(self):
|
||||
@@ -194,7 +192,7 @@ def make_lead(**args):
|
||||
"doctype": "Lead",
|
||||
"first_name": args.first_name or "_Test",
|
||||
"last_name": args.last_name or "Lead",
|
||||
"email_id": args.email_id or "new_lead_{}@example.com".format(random_string(5)),
|
||||
"email_id": args.email_id or f"new_lead_{random_string(5)}@example.com",
|
||||
"company_name": args.company_name or "_Test Company",
|
||||
}
|
||||
).insert()
|
||||
|
||||
@@ -19,14 +19,14 @@ class LinkedInSettings(Document):
|
||||
{
|
||||
"response_type": "code",
|
||||
"client_id": self.consumer_key,
|
||||
"redirect_uri": "{0}/api/method/erpnext.crm.doctype.linkedin_settings.linkedin_settings.callback?".format(
|
||||
"redirect_uri": "{}/api/method/erpnext.crm.doctype.linkedin_settings.linkedin_settings.callback?".format(
|
||||
frappe.utils.get_url()
|
||||
),
|
||||
"scope": "r_emailaddress w_organization_social r_basicprofile r_liteprofile r_organization_social rw_organization_admin w_member_social",
|
||||
}
|
||||
)
|
||||
|
||||
url = "https://www.linkedin.com/oauth/v2/authorization?{}".format(params)
|
||||
url = f"https://www.linkedin.com/oauth/v2/authorization?{params}"
|
||||
|
||||
return url
|
||||
|
||||
@@ -37,7 +37,7 @@ class LinkedInSettings(Document):
|
||||
"code": code,
|
||||
"client_id": self.consumer_key,
|
||||
"client_secret": self.get_password(fieldname="consumer_secret"),
|
||||
"redirect_uri": "{0}/api/method/erpnext.crm.doctype.linkedin_settings.linkedin_settings.callback?".format(
|
||||
"redirect_uri": "{}/api/method/erpnext.crm.doctype.linkedin_settings.linkedin_settings.callback?".format(
|
||||
frappe.utils.get_url()
|
||||
),
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class LinkedInSettings(Document):
|
||||
body = {
|
||||
"registerUploadRequest": {
|
||||
"recipes": ["urn:li:digitalmediaRecipe:feedshare-image"],
|
||||
"owner": "urn:li:organization:{0}".format(self.company_id),
|
||||
"owner": f"urn:li:organization:{self.company_id}",
|
||||
"serviceRelationships": [
|
||||
{"relationshipType": "OWNER", "identifier": "urn:li:userGeneratedContent"}
|
||||
],
|
||||
@@ -100,7 +100,7 @@ class LinkedInSettings(Document):
|
||||
if response.status_code < 200 and response.status_code > 299:
|
||||
frappe.throw(
|
||||
_("Error While Uploading Image"),
|
||||
title="{0} {1}".format(response.status_code, response.reason),
|
||||
title=f"{response.status_code} {response.reason}",
|
||||
)
|
||||
return None
|
||||
return asset
|
||||
@@ -115,7 +115,7 @@ class LinkedInSettings(Document):
|
||||
|
||||
body = {
|
||||
"distribution": {"linkedInDistributionTarget": {}},
|
||||
"owner": "urn:li:organization:{0}".format(self.company_id),
|
||||
"owner": f"urn:li:organization:{self.company_id}",
|
||||
"subject": title,
|
||||
"text": {"text": text},
|
||||
}
|
||||
@@ -136,13 +136,13 @@ class LinkedInSettings(Document):
|
||||
if response.status_code not in [201, 200]:
|
||||
raise
|
||||
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
self.api_error(response)
|
||||
|
||||
return response
|
||||
|
||||
def get_headers(self):
|
||||
return {"Authorization": "Bearer {}".format(self.access_token)}
|
||||
return {"Authorization": f"Bearer {self.access_token}"}
|
||||
|
||||
def get_reference_url(self, text):
|
||||
import re
|
||||
@@ -155,7 +155,7 @@ class LinkedInSettings(Document):
|
||||
def delete_post(self, post_id):
|
||||
try:
|
||||
response = requests.delete(
|
||||
url="https://api.linkedin.com/v2/shares/urn:li:share:{0}".format(post_id),
|
||||
url=f"https://api.linkedin.com/v2/shares/urn:li:share:{post_id}",
|
||||
headers=self.get_headers(),
|
||||
)
|
||||
if response.status_code != 200:
|
||||
@@ -164,7 +164,7 @@ class LinkedInSettings(Document):
|
||||
self.api_error(response)
|
||||
|
||||
def get_post(self, post_id):
|
||||
url = "https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:{0}&shares[0]=urn:li:share:{1}".format(
|
||||
url = "https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:{}&shares[0]=urn:li:share:{}".format(
|
||||
self.company_id, post_id
|
||||
)
|
||||
|
||||
|
||||
@@ -304,9 +304,7 @@ def make_quotation(source_name, target_doc=None):
|
||||
quotation.conversion_rate = exchange_rate
|
||||
|
||||
# get default taxes
|
||||
taxes = get_default_taxes_and_charges(
|
||||
"Sales Taxes and Charges Template", company=quotation.company
|
||||
)
|
||||
taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template", company=quotation.company)
|
||||
if taxes.get("taxes"):
|
||||
quotation.update(taxes)
|
||||
|
||||
@@ -412,9 +410,7 @@ def set_multiple_status(names, status):
|
||||
|
||||
def auto_close_opportunity():
|
||||
"""auto close the `Replied` Opportunities after 7 days"""
|
||||
auto_close_after_days = (
|
||||
frappe.db.get_single_value("CRM Settings", "close_opportunity_after_days") or 15
|
||||
)
|
||||
auto_close_after_days = frappe.db.get_single_value("CRM Settings", "close_opportunity_after_days") or 15
|
||||
|
||||
table = frappe.qb.DocType("Opportunity")
|
||||
opportunities = (
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.utils import add_days, now_datetime, random_string, today
|
||||
from frappe.utils import now_datetime, random_string, today
|
||||
|
||||
from erpnext.crm.doctype.lead.lead import make_customer
|
||||
from erpnext.crm.doctype.lead.test_lead import make_lead
|
||||
@@ -32,9 +32,7 @@ class TestOpportunity(unittest.TestCase):
|
||||
|
||||
self.assertTrue(opp_doc.party_name)
|
||||
self.assertEqual(opp_doc.opportunity_from, "Lead")
|
||||
self.assertEqual(
|
||||
frappe.db.get_value("Lead", opp_doc.party_name, "email_id"), opp_doc.contact_email
|
||||
)
|
||||
self.assertEqual(frappe.db.get_value("Lead", opp_doc.party_name, "email_id"), opp_doc.contact_email)
|
||||
|
||||
# create new customer and create new contact against 'new.opportunity@example.com'
|
||||
customer = make_customer(opp_doc.party_name).insert(ignore_permissions=True)
|
||||
@@ -53,9 +51,7 @@ class TestOpportunity(unittest.TestCase):
|
||||
self.assertEqual(opportunity_doc.total, 2200)
|
||||
|
||||
def test_carry_forward_of_email_and_comments(self):
|
||||
frappe.db.set_value(
|
||||
"CRM Settings", "CRM Settings", "carry_forward_communication_and_comments", 1
|
||||
)
|
||||
frappe.db.set_value("CRM Settings", "CRM Settings", "carry_forward_communication_and_comments", 1)
|
||||
lead_doc = make_lead()
|
||||
lead_doc.add_comment("Comment", text="Test Comment 1")
|
||||
lead_doc.add_comment("Comment", text="Test Comment 2")
|
||||
@@ -66,9 +62,7 @@ class TestOpportunity(unittest.TestCase):
|
||||
opportunity_comment_count = frappe.db.count(
|
||||
"Comment", {"reference_doctype": opp_doc.doctype, "reference_name": opp_doc.name}
|
||||
)
|
||||
opportunity_communication_count = len(
|
||||
get_linked_communication_list(opp_doc.doctype, opp_doc.name)
|
||||
)
|
||||
opportunity_communication_count = len(get_linked_communication_list(opp_doc.doctype, opp_doc.name))
|
||||
self.assertEqual(opportunity_comment_count, 2)
|
||||
self.assertEqual(opportunity_communication_count, 2)
|
||||
|
||||
@@ -79,7 +73,7 @@ class TestOpportunity(unittest.TestCase):
|
||||
|
||||
|
||||
def make_opportunity_from_lead():
|
||||
new_lead_email_id = "new{}@example.com".format(random_string(5))
|
||||
new_lead_email_id = f"new{random_string(5)}@example.com"
|
||||
args = {
|
||||
"doctype": "Opportunity",
|
||||
"contact_email": new_lead_email_id,
|
||||
@@ -128,9 +122,7 @@ def make_opportunity(**args):
|
||||
return opp_doc
|
||||
|
||||
|
||||
def create_communication(
|
||||
reference_doctype, reference_name, sender, sent_or_received=None, creation=None
|
||||
):
|
||||
def create_communication(reference_doctype, reference_name, sender, sent_or_received=None, creation=None):
|
||||
communication = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Communication",
|
||||
|
||||
@@ -34,7 +34,7 @@ def make_prospect(**args):
|
||||
prospect_doc = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Prospect",
|
||||
"company_name": args.company_name or "_Test Company {}".format(random_string(3)),
|
||||
"company_name": args.company_name or f"_Test Company {random_string(3)}",
|
||||
}
|
||||
).insert()
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class SocialMediaPost(Document):
|
||||
def submit(self):
|
||||
if self.scheduled_time:
|
||||
self.post_status = "Scheduled"
|
||||
super(SocialMediaPost, self).submit()
|
||||
super().submit()
|
||||
|
||||
def on_cancel(self):
|
||||
self.db_set("post_status", "Cancelled")
|
||||
|
||||
@@ -16,10 +16,8 @@ from tweepy.error import TweepError
|
||||
class TwitterSettings(Document):
|
||||
@frappe.whitelist()
|
||||
def get_authorize_url(self):
|
||||
callback_url = (
|
||||
"{0}/api/method/erpnext.crm.doctype.twitter_settings.twitter_settings.callback?".format(
|
||||
frappe.utils.get_url()
|
||||
)
|
||||
callback_url = "{}/api/method/erpnext.crm.doctype.twitter_settings.twitter_settings.callback?".format(
|
||||
frappe.utils.get_url()
|
||||
)
|
||||
auth = tweepy.OAuthHandler(
|
||||
self.consumer_key, self.get_password(fieldname="consumer_secret"), callback_url
|
||||
@@ -27,10 +25,12 @@ class TwitterSettings(Document):
|
||||
try:
|
||||
redirect_url = auth.get_authorization_url()
|
||||
return redirect_url
|
||||
except tweepy.TweepError as e:
|
||||
except tweepy.TweepError:
|
||||
frappe.msgprint(_("Error! Failed to get request token."))
|
||||
frappe.throw(
|
||||
_("Invalid {0} or {1}").format(frappe.bold("Consumer Key"), frappe.bold("Consumer Secret Key"))
|
||||
_("Invalid {0} or {1}").format(
|
||||
frappe.bold("Consumer Key"), frappe.bold("Consumer Secret Key")
|
||||
)
|
||||
)
|
||||
|
||||
def get_access_token(self, oauth_token, oauth_verifier):
|
||||
@@ -59,7 +59,7 @@ class TwitterSettings(Document):
|
||||
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = get_url_to_form("Twitter Settings", "Twitter Settings")
|
||||
except TweepError as e:
|
||||
except TweepError:
|
||||
frappe.msgprint(_("Error! Failed to get access token."))
|
||||
frappe.throw(_("Invalid Consumer Key or Consumer Secret Key"))
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import frappe
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_last_interaction(contact=None, lead=None):
|
||||
|
||||
if not contact and not lead:
|
||||
return
|
||||
|
||||
@@ -23,16 +22,14 @@ def get_last_interaction(contact=None, lead=None):
|
||||
# remove extra appended 'OR'
|
||||
query_condition = query_condition[:-2]
|
||||
last_communication = frappe.db.sql(
|
||||
"""
|
||||
f"""
|
||||
SELECT `name`, `content`
|
||||
FROM `tabCommunication`
|
||||
WHERE `sent_or_received`='Received'
|
||||
AND ({})
|
||||
AND ({query_condition})
|
||||
ORDER BY `modified`
|
||||
LIMIT 1
|
||||
""".format(
|
||||
query_condition
|
||||
),
|
||||
""",
|
||||
values,
|
||||
as_dict=1,
|
||||
) # nosec
|
||||
|
||||
@@ -33,13 +33,11 @@ def get_lead_data(filters, based_on):
|
||||
conditions = get_filter_conditions(filters)
|
||||
|
||||
lead_details = frappe.db.sql(
|
||||
"""
|
||||
f"""
|
||||
select {based_on_field}, name
|
||||
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,
|
||||
)
|
||||
@@ -82,9 +80,7 @@ def get_lead_quotation_count(leads):
|
||||
where quotation_to = 'Lead' and party_name in (%s)"""
|
||||
% ", ".join(["%s"] * len(leads)),
|
||||
tuple(leads),
|
||||
)[0][
|
||||
0
|
||||
] # nosec
|
||||
)[0][0] # nosec
|
||||
|
||||
|
||||
def get_lead_opp_count(leads):
|
||||
|
||||
@@ -67,7 +67,7 @@ def get_columns():
|
||||
|
||||
def get_data(filters):
|
||||
return frappe.db.sql(
|
||||
"""
|
||||
f"""
|
||||
SELECT
|
||||
`tabOpportunity`.name,
|
||||
`tabOpportunity`.opportunity_from,
|
||||
@@ -79,17 +79,15 @@ def get_data(filters):
|
||||
`tabOpportunity`.territory
|
||||
FROM
|
||||
`tabOpportunity`
|
||||
{join}
|
||||
{get_join(filters)}
|
||||
WHERE
|
||||
`tabOpportunity`.status = 'Lost' and `tabOpportunity`.company = %(company)s
|
||||
AND DATE(`tabOpportunity`.modified) BETWEEN %(from_date)s AND %(to_date)s
|
||||
{conditions}
|
||||
{get_conditions(filters)}
|
||||
GROUP BY
|
||||
`tabOpportunity`.name
|
||||
ORDER BY
|
||||
`tabOpportunity`.creation asc """.format(
|
||||
conditions=get_conditions(filters), join=get_join(filters)
|
||||
),
|
||||
`tabOpportunity`.creation asc """,
|
||||
filters,
|
||||
as_dict=1,
|
||||
)
|
||||
@@ -119,9 +117,7 @@ def get_join(filters):
|
||||
join = """JOIN `tabOpportunity Lost Reason Detail`
|
||||
ON `tabOpportunity Lost Reason Detail`.parenttype = 'Opportunity' and
|
||||
`tabOpportunity Lost Reason Detail`.parent = `tabOpportunity`.name and
|
||||
`tabOpportunity Lost Reason Detail`.lost_reason = '{0}'
|
||||
""".format(
|
||||
filters.get("lost_reason")
|
||||
)
|
||||
`tabOpportunity Lost Reason Detail`.lost_reason = '{}'
|
||||
""".format(filters.get("lost_reason"))
|
||||
|
||||
return join
|
||||
|
||||
@@ -14,7 +14,7 @@ def execute(filters=None):
|
||||
return OpportunitySummaryBySalesStage(filters).run()
|
||||
|
||||
|
||||
class OpportunitySummaryBySalesStage(object):
|
||||
class OpportunitySummaryBySalesStage:
|
||||
def __init__(self, filters=None):
|
||||
self.filters = frappe._dict(filters or {})
|
||||
|
||||
@@ -199,7 +199,6 @@ class OpportunitySummaryBySalesStage(object):
|
||||
return filters
|
||||
|
||||
def get_chart_data(self):
|
||||
labels = []
|
||||
datasets = []
|
||||
values = [0] * len(self.sales_stage_list)
|
||||
|
||||
|
||||
@@ -62,9 +62,7 @@ def get_data(filters):
|
||||
lead_details = []
|
||||
lead_filters = get_lead_filters(filters)
|
||||
|
||||
for lead in frappe.get_all(
|
||||
"Lead", fields=["name", "lead_name", "company_name"], filters=lead_filters
|
||||
):
|
||||
for lead in frappe.get_all("Lead", fields=["name", "lead_name", "company_name"], filters=lead_filters):
|
||||
data = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
@@ -90,7 +88,7 @@ def get_data(filters):
|
||||
)
|
||||
|
||||
for lead_info in data:
|
||||
lead_data = [lead.name, lead.lead_name, lead.company_name] + list(lead_info)
|
||||
lead_data = [lead.name, lead.lead_name, lead.company_name, *list(lead_info)]
|
||||
lead_details.append(lead_data)
|
||||
|
||||
return lead_details
|
||||
|
||||
@@ -17,7 +17,7 @@ def execute(filters=None):
|
||||
return SalesPipelineAnalytics(filters).run()
|
||||
|
||||
|
||||
class SalesPipelineAnalytics(object):
|
||||
class SalesPipelineAnalytics:
|
||||
def __init__(self, filters=None):
|
||||
self.filters = frappe._dict(filters or {})
|
||||
|
||||
@@ -98,7 +98,7 @@ class SalesPipelineAnalytics(object):
|
||||
"Opportunity",
|
||||
filters=self.get_conditions(),
|
||||
fields=[self.based_on, self.data_based_on, self.duration],
|
||||
group_by="{},{}".format(self.group_by_based_on, self.group_by_period),
|
||||
group_by=f"{self.group_by_based_on},{self.group_by_period}",
|
||||
order_by=self.group_by_period,
|
||||
)
|
||||
|
||||
@@ -230,7 +230,7 @@ class SalesPipelineAnalytics(object):
|
||||
current_date = date.today()
|
||||
month_number = date.today().month
|
||||
|
||||
for month in range(month_number, 13):
|
||||
for _month in range(month_number, 13):
|
||||
month_list.append(current_date.strftime("%B"))
|
||||
current_date = current_date + relativedelta(months=1)
|
||||
|
||||
|
||||
@@ -94,9 +94,7 @@ def get_linked_prospect(reference_doctype, reference_name):
|
||||
"Opportunity", reference_name, ["opportunity_from", "party_name"]
|
||||
)
|
||||
if opportunity_from == "Lead":
|
||||
prospect = frappe.db.get_value(
|
||||
"Prospect Opportunity", {"opportunity": reference_name}, "parent"
|
||||
)
|
||||
prospect = frappe.db.get_value("Prospect Opportunity", {"opportunity": reference_name}, "parent")
|
||||
if opportunity_from == "Prospect":
|
||||
prospect = party_name
|
||||
|
||||
|
||||
Reference in New Issue
Block a user