refactor(treewide): formatting and ruff fixes, + manually enabled F401

Signed-off-by: Akhil Narang <me@akhilnarang.dev>
This commit is contained in:
Akhil Narang
2024-03-27 11:37:26 +05:30
parent c28d19cf7f
commit 4d34b1ead7
618 changed files with 4188 additions and 6384 deletions

View File

@@ -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

View File

@@ -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"))

View File

@@ -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)

View File

@@ -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",
)

View File

@@ -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()

View File

@@ -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
)

View File

@@ -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 = (

View File

@@ -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",

View File

@@ -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()

View File

@@ -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")

View File

@@ -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"))

View File

@@ -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

View File

@@ -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):

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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