Skip to content

Commit b46fdc2

Browse files
authored
Merge pull request #47867 from frappe/version-14-hotfix
chore: release v14
2 parents caf0f2c + df779bb commit b46fdc2

File tree

5 files changed

+67
-34
lines changed

5 files changed

+67
-34
lines changed

erpnext/accounts/report/accounts_receivable/accounts_receivable.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ def get_data(self):
118118
self.build_data()
119119

120120
def fetch_ple_in_buffered_cursor(self):
121-
self.ple_entries = frappe.db.sql(self.ple_query.get_sql(), as_dict=True)
121+
query, param = self.ple_query.walk()
122+
self.ple_entries = frappe.db.sql(query, param, as_dict=True)
122123

123124
for ple in self.ple_entries:
124125
self.init_voucher_balance(ple) # invoiced, paid, credit_note, outstanding
@@ -131,8 +132,9 @@ def fetch_ple_in_buffered_cursor(self):
131132

132133
def fetch_ple_in_unbuffered_cursor(self):
133134
self.ple_entries = []
135+
query, param = self.ple_query.walk()
134136
with frappe.db.unbuffered_cursor():
135-
for ple in frappe.db.sql(self.ple_query.get_sql(), as_dict=True, as_iterator=True):
137+
for ple in frappe.db.sql(query, param, as_dict=True, as_iterator=True):
136138
self.init_voucher_balance(ple) # invoiced, paid, credit_note, outstanding
137139
self.ple_entries.append(ple)
138140

erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def get_columns():
2323
"""return columns"""
2424
columns = [
2525
_("Item") + ":Link/Item:150",
26+
_("Item Name") + "::240",
2627
_("Description") + "::300",
2728
_("BOM Qty") + ":Float:160",
2829
_("BOM UoM") + "::160",
@@ -73,6 +74,7 @@ def get_bom_stock(filters):
7374
.on((BOM_ITEM.item_code == BIN.item_code) & (CONDITIONS))
7475
.select(
7576
BOM_ITEM.item_code,
77+
BOM_ITEM.item_name,
7678
BOM_ITEM.description,
7779
BOM_ITEM.stock_qty,
7880
BOM_ITEM.stock_uom,

erpnext/manufacturing/report/bom_stock_report/test_bom_stock_report.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def get_expected_data(bom, warehouse, qty_to_produce, show_exploded_view=False):
9494
expected_data.append(
9595
[
9696
item.item_code,
97+
item.item_name,
9798
item.description,
9899
item.stock_qty,
99100
item.stock_uom,

erpnext/stock/doctype/material_request/material_request.js

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -497,26 +497,23 @@ erpnext.buying.MaterialRequestController = class MaterialRequestController exten
497497
}
498498

499499
onload(doc, cdt, cdn) {
500-
this.frm.set_query("item_code", "items", function() {
500+
this.frm.set_query("item_code", "items", function () {
501+
let filters = { is_stock_item: 1 };
502+
501503
if (doc.material_request_type == "Customer Provided") {
502-
return{
503-
query: "erpnext.controllers.queries.item_query",
504-
filters:{
505-
'customer': me.frm.doc.customer,
506-
'is_stock_item':1
507-
}
508-
}
509-
} else if (doc.material_request_type == "Purchase") {
510-
return{
511-
query: "erpnext.controllers.queries.item_query",
512-
filters: {'is_purchase_item': 1}
513-
}
514-
} else {
515-
return{
516-
query: "erpnext.controllers.queries.item_query",
517-
filters: {'is_stock_item': 1}
518-
}
504+
filters.customer = doc.customer;
505+
} else if (
506+
doc.material_request_type == "Purchase"
507+
) {
508+
filters = { is_purchase_item: 1 };
509+
} else if (doc.material_request_type == "Manufacture") {
510+
filters.include_item_in_manufacturing = 1;
519511
}
512+
513+
return {
514+
query: "erpnext.controllers.queries.item_query",
515+
filters: filters,
516+
};
520517
});
521518
}
522519

erpnext/stock/report/product_bundle_balance/product_bundle_balance.py

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import frappe
66
from frappe import _
7-
from frappe.query_builder.functions import IfNull
7+
from frappe.query_builder.functions import IfNull, Max
88
from frappe.utils import flt
99
from pypika.terms import ExistsCriterion
1010

@@ -208,29 +208,54 @@ def get_stock_ledger_entries(filters, items):
208208
if not items:
209209
return []
210210

211-
sle = frappe.qb.DocType("Stock Ledger Entry")
212-
sle2 = frappe.qb.DocType("Stock Ledger Entry")
211+
max_posting_datetime_query = get_item_wise_max_posting_datetime(filters, items)
213212

213+
sle = frappe.qb.DocType("Stock Ledger Entry")
214214
query = (
215215
frappe.qb.from_(sle)
216-
.left_join(sle2)
216+
.join(max_posting_datetime_query)
217217
.on(
218-
(sle.item_code == sle2.item_code)
219-
& (sle.warehouse == sle2.warehouse)
220-
& (sle.posting_datetime < sle2.posting_datetime)
221-
& (sle.name < sle2.name)
218+
(sle.item_code == max_posting_datetime_query.item_code)
219+
& (sle.warehouse == max_posting_datetime_query.warehouse)
220+
& (sle.posting_datetime == max_posting_datetime_query.posting_datetime)
222221
)
223222
.select(sle.item_code, sle.warehouse, sle.qty_after_transaction, sle.company)
224-
.where((sle2.name.isnull()) & (sle.docstatus < 2) & (sle.item_code.isin(items)))
223+
.where(sle.is_cancelled == 0)
225224
)
226225

226+
if filters.get("warehouse"):
227+
warehouse_details = frappe.db.get_value(
228+
"Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1
229+
)
230+
231+
if warehouse_details:
232+
wh = frappe.qb.DocType("Warehouse")
233+
query = query.where(
234+
sle.warehouse.isin(
235+
frappe.qb.from_(wh)
236+
.select(wh.name)
237+
.where((wh.lft >= warehouse_details.lft) & (wh.rgt <= warehouse_details.rgt))
238+
)
239+
)
240+
227241
if filters.get("company"):
228242
query = query.where(sle.company == filters.get("company"))
229243

230-
if date := filters.get("date"):
231-
query = query.where(sle.posting_date <= date)
232-
else:
233-
frappe.throw(_("'Date' is required"))
244+
if filters.get("data"):
245+
query = query.where(sle.posting_date <= filters.get("data"))
246+
247+
return query.run(as_dict=True)
248+
249+
250+
def get_item_wise_max_posting_datetime(filters, items):
251+
"""Get the maximum Stock Ledger Entry name for the given filters and items."""
252+
sle = frappe.qb.DocType("Stock Ledger Entry")
253+
query = (
254+
frappe.qb.from_(sle)
255+
.select(sle.item_code, sle.warehouse, sle.name, Max(sle.posting_datetime).as_("posting_datetime"))
256+
.where(sle.item_code.isin(items) & (sle.is_cancelled == 0))
257+
.groupby(sle.item_code, sle.warehouse)
258+
)
234259

235260
if filters.get("warehouse"):
236261
warehouse_details = frappe.db.get_value(
@@ -247,4 +272,10 @@ def get_stock_ledger_entries(filters, items):
247272
)
248273
)
249274

250-
return query.run(as_dict=True)
275+
if filters.get("company"):
276+
query = query.where(sle.company == filters.get("company"))
277+
278+
if filters.get("data"):
279+
query = query.where(sle.posting_date <= filters.get("data"))
280+
281+
return query

0 commit comments

Comments
 (0)