StockReservation.transfer_reservation_entries_to() created the transferred SREs without copying stock_uom, in both the entries_to_reserve dict and the extra-items fallback. get_items_to_reserve() already selects the item's stock_uom, so entry.stock_uom is used.
On sites with a global default stock_uom (e.g. "Nos"), frappe's _set_defaults() backfilled the blank field, so the transfer silently stored the wrong UOM for any item whose stock UOM is not the default. On sites without that default the SRE's validate_mandatory() raised "Stock UOM is required", aborting Work Order submission for the Subcontracting Inward Order / Production Plan flows.
(cherry picked from commit 5991ecfa3d)
make_all_scorecards' dedup query used strict bounds, so a single-day
period (supplier created on a month's last day -> start == end under
"Per Month") never matched its own window and was re-created on every
call. The daily refresh_scorecards job would insert a duplicate
submitted period each day for such suppliers, and
test_make_all_scorecards_is_idempotent fails on any date where
nowdate() - 75 days lands on a month end — both nightly server suites
went red on 2026-07-14 (75 days after April 30).
Inclusive bounds cannot false-match adjacent periods: each next period
starts at end_date + 1, so closed intervals never touch.
covers sales order, quotation, sales invoice, delivery note and
purchase order, asserting actual_qty from the row warehouse and
company_total_stock across all warehouses of the company.
company was passed to get_bin_details only for purchase order, so
company_total_stock was never returned for sales order, quotation,
sales invoice and delivery note and the qty (company) column always
read zero. pass ctx.company for every doctype, which also drops the
dependency on doc being supplied.
on the client, set_actual_qty copied only actual_qty out of the
response, so qty (company) never refreshed on a warehouse change. use
frm.call with child so every bin field is applied, pass
include_child_warehouses to match the server, and include quotation.
- allow new rows on scan when pick manually is enabled, since only
then are scanned rows not subject to being overridden by
set_item_locations on save
- stop capping picked qty at the default demand qty (1) for rows
added by the scanner itself, so repeat scans of the same barcode
keep incrementing the row instead of failing with "maximum
quantity scanned"
- ignore barcode uom when matching an existing row if new rows
aren't allowed, since there's no alternate-uom row to fall back to
#56871 routed any searchfield without a DocField meta — including
"name", which get_search_fields() always appends — into the
`= cint(txt)` branch. For non-numeric search text cint() yields 0, so
`is_group = 0` (Cost Center) matched every leaf record on both
engines, and `name = 0` matched every non-numeric name on MariaDB.
Skip Check fields from or_filters entirely — a checkbox can't match
search text — and keep LIKE for everything else, including "name".
* feat: explain FIFO allocation of fixed Discount Amount on Sales Order (#56436)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Diptanil Saha <diptanil@frappe.io>
(cherry picked from commit 62fed1d562)
# Conflicts:
# erpnext/selling/doctype/sales_order/sales_order.json
* chore: resolved conflicts
---------
Co-authored-by: Mohammad Umair Sayed <umair_sayyed@yahoo.com>
Co-authored-by: Diptanil Saha <diptanil@frappe.io>
Fetch job_card_item for all pick list locations in one query instead
of one per row, and prefer the job card's semi_fg_bom over the work
order BOM, mirroring the direct Job Card -> Stock Entry mapper.
hoist the invariant work order lookup and batch-fetch work order item
source warehouses once instead of querying per raw material row in
get_bom_raw_materials