refactor: DB independent quoting and truthy/falsy values (#31358)

* refactor: DB independent quoting and truthy/falsy values

* style: reformat to black spec

* fix: ifnull -> coalesce

* fix: coalesce -> Coalesce

* fix: revert pypika comparison

* refactor: convert queries to QB

* fix: incorrect value types for query

`=` query makes no sense with list of values

* fix: remove warehouse docstatus condition

* fix: keep using base rate as rate

Co-authored-by: Ankush Menat <ankush@frappe.io>
This commit is contained in:
Conor
2022-06-17 06:31:27 -05:00
committed by GitHub
parent d6078aa911
commit 74a782d81d
43 changed files with 109 additions and 99 deletions

View File

@@ -416,7 +416,7 @@ class JournalEntry(AccountsController):
against_entries = frappe.db.sql( against_entries = frappe.db.sql(
"""select * from `tabJournal Entry Account` """select * from `tabJournal Entry Account`
where account = %s and docstatus = 1 and parent = %s where account = %s and docstatus = 1 and parent = %s
and (reference_type is null or reference_type in ("", "Sales Order", "Purchase Order")) and (reference_type is null or reference_type in ('', 'Sales Order', 'Purchase Order'))
""", """,
(d.account, d.reference_name), (d.account, d.reference_name),
as_dict=True, as_dict=True,

View File

@@ -145,13 +145,14 @@ class Subscription(Document):
You shouldn't need to call this directly. Use `get_billing_cycle` instead. You shouldn't need to call this directly. Use `get_billing_cycle` instead.
""" """
plan_names = [plan.plan for plan in self.plans] plan_names = [plan.plan for plan in self.plans]
billing_info = frappe.db.sql(
"select distinct `billing_interval`, `billing_interval_count` " subscription_plan = frappe.qb.DocType("Subscription Plan")
"from `tabSubscription Plan` " billing_info = (
"where name in %s", frappe.qb.from_(subscription_plan)
(plan_names,), .select(subscription_plan.billing_interval, subscription_plan.billing_interval_count)
as_dict=1, .distinct()
) .where(subscription_plan.name.isin(plan_names))
).run(as_dict=1)
return billing_info return billing_info

View File

@@ -179,7 +179,7 @@ def get_sales_invoice_data(filters):
def get_mode_of_payments(filters): def get_mode_of_payments(filters):
mode_of_payments = {} mode_of_payments = {}
invoice_list = get_invoices(filters) invoice_list = get_invoices(filters)
invoice_list_names = ",".join('"' + invoice["name"] + '"' for invoice in invoice_list) invoice_list_names = ",".join("'" + invoice["name"] + "'" for invoice in invoice_list)
if invoice_list: if invoice_list:
inv_mop = frappe.db.sql( inv_mop = frappe.db.sql(
"""select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') as mode_of_payment """select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') as mode_of_payment
@@ -200,7 +200,7 @@ def get_mode_of_payments(filters):
from `tabJournal Entry` a, `tabJournal Entry Account` b from `tabJournal Entry` a, `tabJournal Entry Account` b
where a.name = b.parent where a.name = b.parent
and a.docstatus = 1 and a.docstatus = 1
and b.reference_type = "Sales Invoice" and b.reference_type = 'Sales Invoice'
and b.reference_name in ({invoice_list_names}) and b.reference_name in ({invoice_list_names})
""".format( """.format(
invoice_list_names=invoice_list_names invoice_list_names=invoice_list_names
@@ -228,7 +228,7 @@ def get_invoices(filters):
def get_mode_of_payment_details(filters): def get_mode_of_payment_details(filters):
mode_of_payment_details = {} mode_of_payment_details = {}
invoice_list = get_invoices(filters) invoice_list = get_invoices(filters)
invoice_list_names = ",".join('"' + invoice["name"] + '"' for invoice in invoice_list) invoice_list_names = ",".join("'" + invoice["name"] + "'" for invoice in invoice_list)
if invoice_list: if invoice_list:
inv_mop_detail = frappe.db.sql( inv_mop_detail = frappe.db.sql(
""" """
@@ -259,7 +259,7 @@ def get_mode_of_payment_details(filters):
from `tabJournal Entry` a, `tabJournal Entry Account` b from `tabJournal Entry` a, `tabJournal Entry Account` b
where a.name = b.parent where a.name = b.parent
and a.docstatus = 1 and a.docstatus = 1
and b.reference_type = "Sales Invoice" and b.reference_type = 'Sales Invoice'
and b.reference_name in ({invoice_list_names}) and b.reference_name in ({invoice_list_names})
group by a.owner, a.posting_date, mode_of_payment group by a.owner, a.posting_date, mode_of_payment
) t ) t

View File

@@ -475,7 +475,7 @@ def check_if_advance_entry_modified(args):
select t2.{dr_or_cr} from `tabJournal Entry` t1, `tabJournal Entry Account` t2 select t2.{dr_or_cr} from `tabJournal Entry` t1, `tabJournal Entry Account` t2
where t1.name = t2.parent and t2.account = %(account)s where t1.name = t2.parent and t2.account = %(account)s
and t2.party_type = %(party_type)s and t2.party = %(party)s and t2.party_type = %(party_type)s and t2.party = %(party)s
and (t2.reference_type is null or t2.reference_type in ("", "Sales Order", "Purchase Order")) and (t2.reference_type is null or t2.reference_type in ('', 'Sales Order', 'Purchase Order'))
and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
and t1.docstatus=1 """.format( and t1.docstatus=1 """.format(
dr_or_cr=args.get("dr_or_cr") dr_or_cr=args.get("dr_or_cr")
@@ -495,7 +495,7 @@ def check_if_advance_entry_modified(args):
t1.name = t2.parent and t1.docstatus = 1 t1.name = t2.parent and t1.docstatus = 1
and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s and t1.name = %(voucher_no)s and t2.name = %(voucher_detail_no)s
and t1.party_type = %(party_type)s and t1.party = %(party)s and t1.{0} = %(account)s and t1.party_type = %(party_type)s and t1.party = %(party)s and t1.{0} = %(account)s
and t2.reference_doctype in ("", "Sales Order", "Purchase Order") and t2.reference_doctype in ('', 'Sales Order', 'Purchase Order')
and t2.allocated_amount = %(unreconciled_amount)s and t2.allocated_amount = %(unreconciled_amount)s
""".format( """.format(
party_account_field party_account_field

View File

@@ -47,17 +47,19 @@ def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, nex
team_member = frappe.db.get_value("User", assign_to_member, "email") team_member = frappe.db.get_value("User", assign_to_member, "email")
args = { args = {
"doctype": "Asset Maintenance", "doctype": "Asset Maintenance",
"assign_to": [team_member], "assign_to": team_member,
"name": asset_maintenance_name, "name": asset_maintenance_name,
"description": maintenance_task, "description": maintenance_task,
"date": next_due_date, "date": next_due_date,
} }
if not frappe.db.sql( if not frappe.db.sql(
"""select owner from `tabToDo` """select owner from `tabToDo`
where reference_type=%(doctype)s and reference_name=%(name)s and status="Open" where reference_type=%(doctype)s and reference_name=%(name)s and status='Open'
and owner=%(assign_to)s""", and owner=%(assign_to)s""",
args, args,
): ):
# assign_to function expects a list
args["assign_to"] = [args["assign_to"]]
assign_to.add(args) assign_to.add(args)

View File

@@ -252,7 +252,7 @@ def get_mapped_pi_records():
ON pi_item.`purchase_order` = po.`name` ON pi_item.`purchase_order` = po.`name`
WHERE WHERE
pi_item.docstatus = 1 pi_item.docstatus = 1
AND po.status not in ("Closed","Completed","Cancelled") AND po.status not in ('Closed','Completed','Cancelled')
AND pi_item.po_detail IS NOT NULL AND pi_item.po_detail IS NOT NULL
""" """
) )
@@ -271,7 +271,7 @@ def get_mapped_pr_records():
pr.docstatus=1 pr.docstatus=1
AND pr.name=pr_item.parent AND pr.name=pr_item.parent
AND pr_item.purchase_order_item IS NOT NULL AND pr_item.purchase_order_item IS NOT NULL
AND pr.status not in ("Closed","Completed","Cancelled") AND pr.status not in ('Closed','Completed','Cancelled')
""" """
) )
) )
@@ -302,7 +302,7 @@ def get_po_entries(conditions):
WHERE WHERE
parent.docstatus = 1 parent.docstatus = 1
AND parent.name = child.parent AND parent.name = child.parent
AND parent.status not in ("Closed","Completed","Cancelled") AND parent.status not in ('Closed','Completed','Cancelled')
{conditions} {conditions}
GROUP BY GROUP BY
parent.name, child.item_code parent.name, child.item_code

View File

@@ -2049,7 +2049,7 @@ def get_advance_journal_entries(
journal_entries = frappe.db.sql( journal_entries = frappe.db.sql(
""" """
select select
"Journal Entry" as reference_type, t1.name as reference_name, 'Journal Entry' as reference_type, t1.name as reference_name,
t1.remark as remarks, t2.{0} as amount, t2.name as reference_row, t1.remark as remarks, t2.{0} as amount, t2.name as reference_row,
t2.reference_name as against_order, t2.exchange_rate t2.reference_name as against_order, t2.exchange_rate
from from
@@ -2104,7 +2104,7 @@ def get_advance_payment_entries(
payment_entries_against_order = frappe.db.sql( payment_entries_against_order = frappe.db.sql(
""" """
select select
"Payment Entry" as reference_type, t1.name as reference_name, 'Payment Entry' as reference_type, t1.name as reference_name,
t1.remarks, t2.allocated_amount as amount, t2.name as reference_row, t1.remarks, t2.allocated_amount as amount, t2.name as reference_row,
t2.reference_name as against_order, t1.posting_date, t2.reference_name as against_order, t1.posting_date,
t1.{0} as currency, t1.{4} as exchange_rate t1.{0} as currency, t1.{4} as exchange_rate
@@ -2124,7 +2124,7 @@ def get_advance_payment_entries(
if include_unallocated: if include_unallocated:
unallocated_payment_entries = frappe.db.sql( unallocated_payment_entries = frappe.db.sql(
""" """
select "Payment Entry" as reference_type, name as reference_name, posting_date, select 'Payment Entry' as reference_type, name as reference_name, posting_date,
remarks, unallocated_amount as amount, {2} as exchange_rate, {3} as currency remarks, unallocated_amount as amount, {2} as exchange_rate, {3} as currency
from `tabPayment Entry` from `tabPayment Entry`
where where

View File

@@ -340,12 +340,12 @@ def get_project_name(doctype, txt, searchfield, start, page_len, filters):
fields = get_fields("Project", ["name", "project_name"]) fields = get_fields("Project", ["name", "project_name"])
searchfields = frappe.get_meta("Project").get_search_fields() searchfields = frappe.get_meta("Project").get_search_fields()
searchfields = " or ".join([field + " like %(txt)s" for field in searchfields]) searchfields = " or ".join(["`tabProject`." + field + " like %(txt)s" for field in searchfields])
return frappe.db.sql( return frappe.db.sql(
"""select {fields} from `tabProject` """select {fields} from `tabProject`
where where
`tabProject`.status not in ("Completed", "Cancelled") `tabProject`.status not in ('Completed', 'Cancelled')
and {cond} {scond} {match_cond} and {cond} {scond} {match_cond}
order by order by
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999), if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
@@ -374,7 +374,7 @@ def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len,
from `tabDelivery Note` from `tabDelivery Note`
where `tabDelivery Note`.`%(key)s` like %(txt)s and where `tabDelivery Note`.`%(key)s` like %(txt)s and
`tabDelivery Note`.docstatus = 1 `tabDelivery Note`.docstatus = 1
and status not in ("Stopped", "Closed") %(fcond)s and status not in ('Stopped', 'Closed') %(fcond)s
and ( and (
(`tabDelivery Note`.is_return = 0 and `tabDelivery Note`.per_billed < 100) (`tabDelivery Note`.is_return = 0 and `tabDelivery Note`.per_billed < 100)
or (`tabDelivery Note`.grand_total = 0 and `tabDelivery Note`.per_billed < 100) or (`tabDelivery Note`.grand_total = 0 and `tabDelivery Note`.per_billed < 100)
@@ -654,7 +654,7 @@ def warehouse_query(doctype, txt, searchfield, start, page_len, filters):
filter_dict = get_doctype_wise_filters(filters) filter_dict = get_doctype_wise_filters(filters)
query = """select `tabWarehouse`.name, query = """select `tabWarehouse`.name,
CONCAT_WS(" : ", "Actual Qty", ifnull(round(`tabBin`.actual_qty, 2), 0 )) actual_qty CONCAT_WS(' : ', 'Actual Qty', ifnull(round(`tabBin`.actual_qty, 2), 0 )) actual_qty
from `tabWarehouse` left join `tabBin` from `tabWarehouse` left join `tabBin`
on `tabBin`.warehouse = `tabWarehouse`.name {bin_conditions} on `tabBin`.warehouse = `tabWarehouse`.name {bin_conditions}
where where

View File

@@ -352,9 +352,9 @@ class StatusUpdater(Document):
for args in self.status_updater: for args in self.status_updater:
# condition to include current record (if submit or no if cancel) # condition to include current record (if submit or no if cancel)
if self.docstatus == 1: if self.docstatus == 1:
args["cond"] = ' or parent="%s"' % self.name.replace('"', '"') args["cond"] = " or parent='%s'" % self.name.replace('"', '"')
else: else:
args["cond"] = ' and parent!="%s"' % self.name.replace('"', '"') args["cond"] = " and parent!='%s'" % self.name.replace('"', '"')
self._update_children(args, update_modified) self._update_children(args, update_modified)
@@ -384,7 +384,7 @@ class StatusUpdater(Document):
args["second_source_condition"] = frappe.db.sql( args["second_source_condition"] = frappe.db.sql(
""" select ifnull((select sum(%(second_source_field)s) """ select ifnull((select sum(%(second_source_field)s)
from `tab%(second_source_dt)s` from `tab%(second_source_dt)s`
where `%(second_join_field)s`="%(detail_id)s" where `%(second_join_field)s`='%(detail_id)s'
and (`tab%(second_source_dt)s`.docstatus=1) and (`tab%(second_source_dt)s`.docstatus=1)
%(second_source_extra_cond)s), 0) """ %(second_source_extra_cond)s), 0) """
% args % args
@@ -398,7 +398,7 @@ class StatusUpdater(Document):
frappe.db.sql( frappe.db.sql(
""" """
(select ifnull(sum(%(source_field)s), 0) (select ifnull(sum(%(source_field)s), 0)
from `tab%(source_dt)s` where `%(join_field)s`="%(detail_id)s" from `tab%(source_dt)s` where `%(join_field)s`='%(detail_id)s'
and (docstatus=1 %(cond)s) %(extra_cond)s) and (docstatus=1 %(cond)s) %(extra_cond)s)
""" """
% args % args
@@ -445,7 +445,7 @@ class StatusUpdater(Document):
ifnull((select ifnull((select
ifnull(sum(if(abs(%(target_ref_field)s) > abs(%(target_field)s), abs(%(target_field)s), abs(%(target_ref_field)s))), 0) ifnull(sum(if(abs(%(target_ref_field)s) > abs(%(target_field)s), abs(%(target_field)s), abs(%(target_ref_field)s))), 0)
/ sum(abs(%(target_ref_field)s)) * 100 / sum(abs(%(target_ref_field)s)) * 100
from `tab%(target_dt)s` where parent="%(name)s" having sum(abs(%(target_ref_field)s)) > 0), 0), 6) from `tab%(target_dt)s` where parent='%(name)s' having sum(abs(%(target_ref_field)s)) > 0), 0), 6)
%(update_modified)s %(update_modified)s
where name='%(name)s'""" where name='%(name)s'"""
% args % args

View File

@@ -23,7 +23,7 @@ class TestMpesaSettings(unittest.TestCase):
def tearDown(self): def tearDown(self):
frappe.db.sql("delete from `tabMpesa Settings`") frappe.db.sql("delete from `tabMpesa Settings`")
frappe.db.sql('delete from `tabIntegration Request` where integration_request_service = "Mpesa"') frappe.db.sql("delete from `tabIntegration Request` where integration_request_service = 'Mpesa'")
def test_creation_of_payment_gateway(self): def test_creation_of_payment_gateway(self):
mode_of_payment = create_mode_of_payment("Mpesa-_Test", payment_type="Phone") mode_of_payment = create_mode_of_payment("Mpesa-_Test", payment_type="Phone")

View File

@@ -88,7 +88,7 @@ def send_exit_questionnaire(interviews):
reference_doctype=interview.doctype, reference_doctype=interview.doctype,
reference_name=interview.name, reference_name=interview.name,
) )
interview.db_set("questionnaire_email_sent", True) interview.db_set("questionnaire_email_sent", 1)
interview.notify_update() interview.notify_update()
email_success.append(email) email_success.append(email)
else: else:

View File

@@ -49,7 +49,7 @@ class TestJobOffer(unittest.TestCase):
frappe.db.set_value("HR Settings", None, "check_vacancies", 1) frappe.db.set_value("HR Settings", None, "check_vacancies", 1)
def tearDown(self): def tearDown(self):
frappe.db.sql("DELETE FROM `tabJob Offer` WHERE 1") frappe.db.sql("DELETE FROM `tabJob Offer`")
def create_job_offer(**args): def create_job_offer(**args):

View File

@@ -399,7 +399,7 @@ class LeaveApplication(Document):
select select
name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
from `tabLeave Application` from `tabLeave Application`
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved") where employee = %(employee)s and docstatus < 2 and status in ('Open', 'Approved')
and to_date >= %(from_date)s and from_date <= %(to_date)s and to_date >= %(from_date)s and from_date <= %(to_date)s
and name != %(name)s""", and name != %(name)s""",
{ {
@@ -439,7 +439,7 @@ class LeaveApplication(Document):
"""select count(name) from `tabLeave Application` """select count(name) from `tabLeave Application`
where employee = %(employee)s where employee = %(employee)s
and docstatus < 2 and docstatus < 2
and status in ("Open", "Approved") and status in ('Open', 'Approved')
and half_day = 1 and half_day = 1
and half_day_date = %(half_day_date)s and half_day_date = %(half_day_date)s
and name != %(name)s""", and name != %(name)s""",
@@ -456,7 +456,7 @@ class LeaveApplication(Document):
def validate_attendance(self): def validate_attendance(self):
attendance = frappe.db.sql( attendance = frappe.db.sql(
"""select name from `tabAttendance` where employee = %s and (attendance_date between %s and %s) """select name from `tabAttendance` where employee = %s and (attendance_date between %s and %s)
and status = "Present" and docstatus = 1""", and status = 'Present' and docstatus = 1""",
(self.employee, self.from_date, self.to_date), (self.employee, self.from_date, self.to_date),
) )
if attendance: if attendance:

View File

@@ -108,7 +108,7 @@ class TestLeaveApplication(unittest.TestCase):
def _clear_roles(self): def _clear_roles(self):
frappe.db.sql( frappe.db.sql(
"""delete from `tabHas Role` where parent in """delete from `tabHas Role` where parent in
("test@example.com", "test1@example.com", "test2@example.com")""" ('test@example.com', 'test1@example.com', 'test2@example.com')"""
) )
def _clear_applications(self): def _clear_applications(self):

View File

@@ -5,6 +5,7 @@ import frappe
from frappe import _ from frappe import _
from frappe.query_builder import Order from frappe.query_builder import Order
from frappe.utils import getdate from frappe.utils import getdate
from pypika import functions as fn
def execute(filters=None): def execute(filters=None):
@@ -110,7 +111,7 @@ def get_data(filters):
) )
.distinct() .distinct()
.where( .where(
((employee.relieving_date.isnotnull()) | (employee.relieving_date != "")) (fn.Coalesce(fn.Cast(employee.relieving_date, "char"), "") != "")
& ((interview.name.isnull()) | ((interview.name.isnotnull()) & (interview.docstatus != 2))) & ((interview.name.isnull()) | ((interview.name.isnotnull()) & (interview.docstatus != 2)))
& ((fnf.name.isnull()) | ((fnf.name.isnotnull()) & (fnf.docstatus != 2))) & ((fnf.name.isnull()) | ((fnf.name.isnotnull()) & (fnf.docstatus != 2)))
) )

View File

@@ -20,7 +20,7 @@ class TestVehicleExpenses(unittest.TestCase):
frappe.db.sql("delete from `tabVehicle Log`") frappe.db.sql("delete from `tabVehicle Log`")
employee_id = frappe.db.sql( employee_id = frappe.db.sql(
'''select name from `tabEmployee` where name="testdriver@example.com"''' """select name from `tabEmployee` where name='testdriver@example.com' """
) )
self.employee_id = employee_id[0][0] if employee_id else None self.employee_id = employee_id[0][0] if employee_id else None
if not self.employee_id: if not self.employee_id:

View File

@@ -458,7 +458,7 @@ def get_salary_assignments(employee, payroll_period):
def get_sal_slip_total_benefit_given(employee, payroll_period, component=False): def get_sal_slip_total_benefit_given(employee, payroll_period, component=False):
total_given_benefit_amount = 0 total_given_benefit_amount = 0
query = """ query = """
select sum(sd.amount) as 'total_amount' select sum(sd.amount) as total_amount
from `tabSalary Slip` ss, `tabSalary Detail` sd from `tabSalary Slip` ss, `tabSalary Detail` sd
where ss.employee=%(employee)s where ss.employee=%(employee)s
and ss.docstatus = 1 and ss.name = sd.parent and ss.docstatus = 1 and ss.name = sd.parent

View File

@@ -1305,7 +1305,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters):
if not field in searchfields if not field in searchfields
] ]
query_filters = {"disabled": 0, "ifnull(end_of_life, '5050-50-50')": (">", today())} query_filters = {"disabled": 0, "end_of_life": (">", today())}
or_cond_filters = {} or_cond_filters = {}
if txt: if txt:

View File

@@ -849,7 +849,7 @@ def get_subitems(
FROM FROM
`tabBOM Item` bom_item `tabBOM Item` bom_item
JOIN `tabBOM` bom ON bom.name = bom_item.parent JOIN `tabBOM` bom ON bom.name = bom_item.parent
JOIN tabItem item ON bom_item.item_code = item.name JOIN `tabItem` item ON bom_item.item_code = item.name
LEFT JOIN `tabItem Default` item_default LEFT JOIN `tabItem Default` item_default
ON item.name = item_default.parent and item_default.company = %(company)s ON item.name = item_default.parent and item_default.company = %(company)s
LEFT JOIN `tabUOM Conversion Detail` item_uom LEFT JOIN `tabUOM Conversion Detail` item_uom
@@ -979,7 +979,7 @@ def get_sales_orders(self):
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
from `tabSales Order` so, `tabSales Order Item` so_item from `tabSales Order` so, `tabSales Order Item` so_item
where so_item.parent = so.name where so_item.parent = so.name
and so.docstatus = 1 and so.status not in ("Stopped", "Closed") and so.docstatus = 1 and so.status not in ('Stopped', 'Closed')
and so.company = %(company)s and so.company = %(company)s
and so_item.qty > so_item.work_order_qty {so_filter} {item_filter} and so_item.qty > so_item.work_order_qty {so_filter} {item_filter}
and (exists (select name from `tabBOM` bom where {bom_item} and (exists (select name from `tabBOM` bom where {bom_item}

View File

@@ -939,7 +939,7 @@ class WorkOrder(Document):
from `tabStock Entry` entry, `tabStock Entry Detail` detail from `tabStock Entry` entry, `tabStock Entry Detail` detail
where where
entry.work_order = %(name)s entry.work_order = %(name)s
and entry.purpose = "Material Transfer for Manufacture" and entry.purpose = 'Material Transfer for Manufacture'
and entry.docstatus = 1 and entry.docstatus = 1
and detail.parent = entry.name and detail.parent = entry.name
and (detail.item_code = %(item)s or detail.original_item = %(item)s)""", and (detail.item_code = %(item)s or detail.original_item = %(item)s)""",

View File

@@ -674,7 +674,7 @@ def get_filter_condition(filters):
def get_joining_relieving_condition(start_date, end_date): def get_joining_relieving_condition(start_date, end_date):
cond = """ cond = """
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(end_date)s' and ifnull(t1.date_of_joining, '1900-01-01') <= '%(end_date)s'
and ifnull(t1.relieving_date, '2199-12-31') >= '%(start_date)s' and ifnull(t1.relieving_date, '2199-12-31') >= '%(start_date)s'
""" % { """ % {
"start_date": start_date, "start_date": start_date,

View File

@@ -508,7 +508,7 @@ class SalarySlip(TransactionBase):
SELECT attendance_date, status, leave_type SELECT attendance_date, status, leave_type
FROM `tabAttendance` FROM `tabAttendance`
WHERE WHERE
status in ("Absent", "Half Day", "On leave") status in ('Absent', 'Half Day', 'On leave')
AND employee = %s AND employee = %s
AND docstatus = 1 AND docstatus = 1
AND attendance_date between %s and %s AND attendance_date between %s and %s

View File

@@ -39,17 +39,17 @@ def get_rows(filters):
FROM FROM
(SELECT (SELECT
si.customer_name,si.base_grand_total, si.customer_name,si.base_grand_total,
si.name as voucher_no,tabTimesheet.employee, si.name as voucher_no,`tabTimesheet`.employee,
tabTimesheet.title as employee_name,tabTimesheet.parent_project as project, `tabTimesheet`.title as employee_name,`tabTimesheet`.parent_project as project,
tabTimesheet.start_date,tabTimesheet.end_date, `tabTimesheet`.start_date,`tabTimesheet`.end_date,
tabTimesheet.total_billed_hours,tabTimesheet.name as timesheet, `tabTimesheet`.total_billed_hours,`tabTimesheet`.name as timesheet,
ss.base_gross_pay,ss.total_working_days, ss.base_gross_pay,ss.total_working_days,
tabTimesheet.total_billed_hours/(ss.total_working_days * {0}) as utilization `tabTimesheet`.total_billed_hours/(ss.total_working_days * {0}) as utilization
FROM FROM
`tabSalary Slip Timesheet` as sst join `tabTimesheet` on tabTimesheet.name = sst.time_sheet `tabSalary Slip Timesheet` as sst join `tabTimesheet` on `tabTimesheet`.name = sst.time_sheet
join `tabSales Invoice Timesheet` as sit on sit.time_sheet = tabTimesheet.name join `tabSales Invoice Timesheet` as sit on sit.time_sheet = `tabTimesheet`.name
join `tabSales Invoice` as si on si.name = sit.parent and si.status != "Cancelled" join `tabSales Invoice` as si on si.name = sit.parent and si.status != 'Cancelled'
join `tabSalary Slip` as ss on ss.name = sst.parent and ss.status != "Cancelled" """.format( join `tabSalary Slip` as ss on ss.name = sst.parent and ss.status != 'Cancelled' """.format(
standard_working_hours standard_working_hours
) )
if conditions: if conditions:
@@ -72,23 +72,25 @@ def get_conditions(filters):
conditions = [] conditions = []
if filters.get("company"): if filters.get("company"):
conditions.append("tabTimesheet.company={0}".format(frappe.db.escape(filters.get("company")))) conditions.append("`tabTimesheet`.company={0}".format(frappe.db.escape(filters.get("company"))))
if filters.get("start_date"): if filters.get("start_date"):
conditions.append("tabTimesheet.start_date>='{0}'".format(filters.get("start_date"))) conditions.append("`tabTimesheet`.start_date>='{0}'".format(filters.get("start_date")))
if filters.get("end_date"): if filters.get("end_date"):
conditions.append("tabTimesheet.end_date<='{0}'".format(filters.get("end_date"))) conditions.append("`tabTimesheet`.end_date<='{0}'".format(filters.get("end_date")))
if filters.get("customer_name"): if filters.get("customer_name"):
conditions.append("si.customer_name={0}".format(frappe.db.escape(filters.get("customer_name")))) conditions.append("si.customer_name={0}".format(frappe.db.escape(filters.get("customer_name"))))
if filters.get("employee"): if filters.get("employee"):
conditions.append("tabTimesheet.employee={0}".format(frappe.db.escape(filters.get("employee")))) conditions.append(
"`tabTimesheet`.employee={0}".format(frappe.db.escape(filters.get("employee")))
)
if filters.get("project"): if filters.get("project"):
conditions.append( conditions.append(
"tabTimesheet.parent_project={0}".format(frappe.db.escape(filters.get("project"))) "`tabTimesheet`.parent_project={0}".format(frappe.db.escape(filters.get("project")))
) )
conditions = " and ".join(conditions) conditions = " and ".join(conditions)

View File

@@ -83,7 +83,7 @@ def get_conditions(filters):
("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"), ("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"),
("company_gstin", " and company_gstin=%(company_gstin)s"), ("company_gstin", " and company_gstin=%(company_gstin)s"),
("from_date", " and posting_date >= %(from_date)s"), ("from_date", " and posting_date >= %(from_date)s"),
("to_date", "and posting_date <= %(to_date)s"), ("to_date", " and posting_date <= %(to_date)s"),
): ):
if filters.get(opts[0]): if filters.get(opts[0]):
conditions += opts[1] conditions += opts[1]

View File

@@ -47,7 +47,7 @@ def execute(filters=None):
s.name = gl.party s.name = gl.party
AND s.irs_1099 = 1 AND s.irs_1099 = 1
AND gl.fiscal_year = %(fiscal_year)s AND gl.fiscal_year = %(fiscal_year)s
AND gl.party_type = "Supplier" AND gl.party_type = 'Supplier'
AND gl.company = %(company)s AND gl.company = %(company)s
{conditions} {conditions}

View File

@@ -65,7 +65,7 @@ class VATAuditReport(object):
`tab{doctype}` `tab{doctype}`
WHERE WHERE
docstatus = 1 {where_conditions} docstatus = 1 {where_conditions}
and is_opening = "No" and is_opening = 'No'
ORDER BY ORDER BY
posting_date DESC posting_date DESC
""".format( """.format(

View File

@@ -267,7 +267,7 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False):
def set_expired_status(): def set_expired_status():
# filter out submitted non expired quotations whose validity has been ended # filter out submitted non expired quotations whose validity has been ended
cond = "qo.docstatus = 1 and qo.status != 'Expired' and qo.valid_till < %s" cond = "`tabQuotation`.docstatus = 1 and `tabQuotation`.status != 'Expired' and `tabQuotation`.valid_till < %s"
# check if those QUO have SO against it # check if those QUO have SO against it
so_against_quo = """ so_against_quo = """
SELECT SELECT
@@ -275,13 +275,18 @@ def set_expired_status():
WHERE WHERE
so_item.docstatus = 1 and so.docstatus = 1 so_item.docstatus = 1 and so.docstatus = 1
and so_item.parent = so.name and so_item.parent = so.name
and so_item.prevdoc_docname = qo.name""" and so_item.prevdoc_docname = `tabQuotation`.name"""
# if not exists any SO, set status as Expired # if not exists any SO, set status as Expired
frappe.db.sql( frappe.db.multisql(
"""UPDATE `tabQuotation` qo SET qo.status = 'Expired' WHERE {cond} and not exists({so_against_quo})""".format( {
cond=cond, so_against_quo=so_against_quo "mariadb": """UPDATE `tabQuotation` SET `tabQuotation`.status = 'Expired' WHERE {cond} and not exists({so_against_quo})""".format(
), cond=cond, so_against_quo=so_against_quo
),
"postgres": """UPDATE `tabQuotation` SET status = 'Expired' FROM `tabSales Order`, `tabSales Order Item` WHERE {cond} and not exists({so_against_quo})""".format(
cond=cond, so_against_quo=so_against_quo
),
},
(nowdate()), (nowdate()),
) )

View File

@@ -329,7 +329,7 @@ class TestSalesOrder(FrappeTestCase):
def test_sales_order_on_hold(self): def test_sales_order_on_hold(self):
so = make_sales_order(item_code="_Test Product Bundle Item") so = make_sales_order(item_code="_Test Product Bundle Item")
so.db_set("Status", "On Hold") so.db_set("status", "On Hold")
si = make_sales_invoice(so.name) si = make_sales_invoice(so.name)
self.assertRaises(frappe.ValidationError, create_dn_against_so, so.name) self.assertRaises(frappe.ValidationError, create_dn_against_so, so.name)
self.assertRaises(frappe.ValidationError, si.submit) self.assertRaises(frappe.ValidationError, si.submit)

View File

@@ -65,7 +65,7 @@ def get_data():
WHERE WHERE
so.docstatus = 1 so.docstatus = 1
and so.name = so_item.parent and so.name = so_item.parent
and so.status not in ("Closed","Completed","Cancelled") and so.status not in ('Closed','Completed','Cancelled')
GROUP BY GROUP BY
so.name,so_item.item_code so.name,so_item.item_code
""", """,

View File

@@ -464,7 +464,7 @@ class Company(NestedSet):
# reset default company # reset default company
frappe.db.sql( frappe.db.sql(
"""update `tabSingles` set value="" """update `tabSingles` set value=''
where doctype='Global Defaults' and field='default_company' where doctype='Global Defaults' and field='default_company'
and value=%s""", and value=%s""",
self.name, self.name,
@@ -472,7 +472,7 @@ class Company(NestedSet):
# reset default company # reset default company
frappe.db.sql( frappe.db.sql(
"""update `tabSingles` set value="" """update `tabSingles` set value=''
where doctype='Chart of Accounts Importer' and field='company' where doctype='Chart of Accounts Importer' and field='company'
and value=%s""", and value=%s""",
self.name, self.name,

View File

@@ -198,7 +198,7 @@ class EmailDigest(Document):
todo_list = frappe.db.sql( todo_list = frappe.db.sql(
"""select * """select *
from `tabToDo` where (owner=%s or assigned_by=%s) and status="Open" from `tabToDo` where (owner=%s or assigned_by=%s) and status='Open'
order by field(priority, 'High', 'Medium', 'Low') asc, date asc limit 20""", order by field(priority, 'High', 'Medium', 'Low') asc, date asc limit 20""",
(user_id, user_id), (user_id, user_id),
as_dict=True, as_dict=True,

View File

@@ -42,7 +42,7 @@ class TransactionDeletionRecord(Document):
def delete_bins(self): def delete_bins(self):
frappe.db.sql( frappe.db.sql(
"""delete from tabBin where warehouse in """delete from `tabBin` where warehouse in
(select name from tabWarehouse where company=%s)""", (select name from tabWarehouse where company=%s)""",
self.company, self.company,
) )
@@ -64,7 +64,7 @@ class TransactionDeletionRecord(Document):
addresses = ["%s" % frappe.db.escape(addr) for addr in addresses] addresses = ["%s" % frappe.db.escape(addr) for addr in addresses]
frappe.db.sql( frappe.db.sql(
"""delete from tabAddress where name in ({addresses}) and """delete from `tabAddress` where name in ({addresses}) and
name not in (select distinct dl1.parent from `tabDynamic Link` dl1 name not in (select distinct dl1.parent from `tabDynamic Link` dl1
inner join `tabDynamic Link` dl2 on dl1.parent=dl2.parent inner join `tabDynamic Link` dl2 on dl1.parent=dl2.parent
and dl1.link_doctype<>dl2.link_doctype)""".format( and dl1.link_doctype<>dl2.link_doctype)""".format(
@@ -80,7 +80,7 @@ class TransactionDeletionRecord(Document):
) )
frappe.db.sql( frappe.db.sql(
"""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format( """update `tabCustomer` set lead_name=NULL where lead_name in ({leads})""".format(
leads=",".join(leads) leads=",".join(leads)
) )
) )
@@ -178,7 +178,7 @@ class TransactionDeletionRecord(Document):
else: else:
last = 0 last = 0
frappe.db.sql("""update tabSeries set current = %s where name=%s""", (last, prefix)) frappe.db.sql("""update `tabSeries` set current = %s where name=%s""", (last, prefix))
def delete_version_log(self, doctype, company_fieldname): def delete_version_log(self, doctype, company_fieldname):
frappe.db.sql( frappe.db.sql(

View File

@@ -263,9 +263,9 @@ def get_default_contact(out, name):
FROM FROM
`tabDynamic Link` dl `tabDynamic Link` dl
WHERE WHERE
dl.link_doctype="Customer" dl.link_doctype='Customer'
AND dl.link_name=%s AND dl.link_name=%s
AND dl.parenttype = "Contact" AND dl.parenttype = 'Contact'
""", """,
(name), (name),
as_dict=1, as_dict=1,
@@ -289,9 +289,9 @@ def get_default_address(out, name):
FROM FROM
`tabDynamic Link` dl `tabDynamic Link` dl
WHERE WHERE
dl.link_doctype="Customer" dl.link_doctype='Customer'
AND dl.link_name=%s AND dl.link_name=%s
AND dl.parenttype = "Address" AND dl.parenttype = 'Address'
""", """,
(name), (name),
as_dict=1, as_dict=1,
@@ -388,7 +388,7 @@ def notify_customers(delivery_trip):
if email_recipients: if email_recipients:
frappe.msgprint(_("Email sent to {0}").format(", ".join(email_recipients))) frappe.msgprint(_("Email sent to {0}").format(", ".join(email_recipients)))
delivery_trip.db_set("email_notification_sent", True) delivery_trip.db_set("email_notification_sent", 1)
else: else:
frappe.msgprint(_("No contacts with email IDs found.")) frappe.msgprint(_("No contacts with email IDs found."))

View File

@@ -1155,7 +1155,7 @@ def check_stock_uom_with_bin(item, stock_uom):
bin_list = frappe.db.sql( bin_list = frappe.db.sql(
""" """
select * from tabBin where item_code = %s select * from `tabBin` where item_code = %s
and (reserved_qty > 0 or ordered_qty > 0 or indented_qty > 0 or planned_qty > 0) and (reserved_qty > 0 or ordered_qty > 0 or indented_qty > 0 or planned_qty > 0)
and stock_uom != %s and stock_uom != %s
""", """,
@@ -1171,7 +1171,7 @@ def check_stock_uom_with_bin(item, stock_uom):
) )
# No SLE or documents against item. Bin UOM can be changed safely. # No SLE or documents against item. Bin UOM can be changed safely.
frappe.db.sql("""update tabBin set stock_uom=%s where item_code=%s""", (stock_uom, item)) frappe.db.sql("""update `tabBin` set stock_uom=%s where item_code=%s""", (stock_uom, item))
def get_item_defaults(item_code, company): def get_item_defaults(item_code, company):

View File

@@ -381,8 +381,8 @@ class TestItem(FrappeTestCase):
frappe.delete_doc_if_exists("Item Attribute", "Test Item Length") frappe.delete_doc_if_exists("Item Attribute", "Test Item Length")
frappe.db.sql( frappe.db.sql(
'''delete from `tabItem Variant Attribute` """delete from `tabItem Variant Attribute`
where attribute="Test Item Length"''' where attribute='Test Item Length' """
) )
frappe.flags.attribute_values = None frappe.flags.attribute_values = None

View File

@@ -611,7 +611,7 @@ def get_items_for_stock_reco(warehouse, company):
select select
i.name as item_code, i.item_name, bin.warehouse as warehouse, i.has_serial_no, i.has_batch_no i.name as item_code, i.item_name, bin.warehouse as warehouse, i.has_serial_no, i.has_batch_no
from from
tabBin bin, tabItem i `tabBin` bin, `tabItem` i
where where
i.name = bin.item_code i.name = bin.item_code
and IFNULL(i.disabled, 0) = 0 and IFNULL(i.disabled, 0) = 0
@@ -629,7 +629,7 @@ def get_items_for_stock_reco(warehouse, company):
select select
i.name as item_code, i.item_name, id.default_warehouse as warehouse, i.has_serial_no, i.has_batch_no i.name as item_code, i.item_name, id.default_warehouse as warehouse, i.has_serial_no, i.has_batch_no
from from
tabItem i, `tabItem Default` id `tabItem` i, `tabItem Default` id
where where
i.name = id.parent i.name = id.parent
and exists( and exists(

View File

@@ -161,8 +161,7 @@ def get_children(doctype, parent=None, company=None, is_root=False):
fields = ["name as value", "is_group as expandable"] fields = ["name as value", "is_group as expandable"]
filters = [ filters = [
["docstatus", "<", "2"], ["ifnull(`parent_warehouse`, '')", "=", parent],
['ifnull(`parent_warehouse`, "")', "=", parent],
["company", "in", (company, None, "")], ["company", "in", (company, None, "")],
] ]

View File

@@ -890,7 +890,7 @@ def get_item_price(args, item_code, ignore_party=False):
return frappe.db.sql( return frappe.db.sql(
""" select name, price_list_rate, uom """ select name, price_list_rate, uom
from `tabItem Price` {conditions} from `tabItem Price` {conditions}
order by valid_from desc, batch_no desc, uom desc """.format( order by valid_from desc, ifnull(batch_no, '') desc, uom desc """.format(
conditions=conditions conditions=conditions
), ),
args, args,

View File

@@ -105,7 +105,7 @@ def get_item_warehouse_projected_qty(items_to_consider):
for item_code, warehouse, projected_qty in frappe.db.sql( for item_code, warehouse, projected_qty in frappe.db.sql(
"""select item_code, warehouse, projected_qty """select item_code, warehouse, projected_qty
from tabBin where item_code in ({0}) from tabBin where item_code in ({0})
and (warehouse != "" and warehouse is not null)""".format( and (warehouse != '' and warehouse is not null)""".format(
", ".join(["%s"] * len(items_to_consider)) ", ".join(["%s"] * len(items_to_consider))
), ),
items_to_consider, items_to_consider,

View File

@@ -73,7 +73,7 @@ def get_stock_ledger_entries(report_filters):
"Stock Ledger Entry", "Stock Ledger Entry",
fields=fields, fields=fields,
filters=filters, filters=filters,
order_by="timestamp(posting_date, posting_time) asc, creation asc", order_by="posting_date asc, posting_time asc, creation asc",
) )

View File

@@ -106,7 +106,7 @@ def get_stock_ledger_entries(report_filters):
"Stock Ledger Entry", "Stock Ledger Entry",
fields=fields, fields=fields,
filters=filters, filters=filters,
order_by="timestamp(posting_date, posting_time) asc, creation asc", order_by="posting_date asc, posting_time asc, creation asc",
) )

View File

@@ -238,7 +238,7 @@ def get_stock_ledger_entries(filters, items):
sl_entries = frappe.db.sql( sl_entries = frappe.db.sql(
""" """
SELECT SELECT
concat_ws(" ", posting_date, posting_time) AS date, concat_ws(' ', posting_date, posting_time) AS date,
item_code, item_code,
warehouse, warehouse,
actual_qty, actual_qty,

View File

@@ -118,7 +118,7 @@ def get_reserved_qty(item_code, warehouse):
select qty, parent_detail_docname, parent, name select qty, parent_detail_docname, parent, name
from `tabPacked Item` dnpi_in from `tabPacked Item` dnpi_in
where item_code = %s and warehouse = %s where item_code = %s and warehouse = %s
and parenttype="Sales Order" and parenttype='Sales Order'
and item_code != parent_item and item_code != parent_item
and exists (select * from `tabSales Order` so and exists (select * from `tabSales Order` so
where name = dnpi_in.parent and docstatus = 1 and status != 'Closed') where name = dnpi_in.parent and docstatus = 1 and status != 'Closed')
@@ -194,7 +194,7 @@ def get_planned_qty(item_code, warehouse):
planned_qty = frappe.db.sql( planned_qty = frappe.db.sql(
""" """
select sum(qty - produced_qty) from `tabWork Order` select sum(qty - produced_qty) from `tabWork Order`
where production_item = %s and fg_warehouse = %s and status not in ("Stopped", "Completed", "Closed") where production_item = %s and fg_warehouse = %s and status not in ('Stopped', 'Completed', 'Closed')
and docstatus=1 and qty > produced_qty""", and docstatus=1 and qty > produced_qty""",
(item_code, warehouse), (item_code, warehouse),
) )