When a Purchase Invoice is created with `update_stock = 1`, the system
automatically replaces the item's expense account with the correct
inventory account for perpetual inventory. This is expected behaviour,
but a `frappe.msgprint` warning was being shown to the user:
"Expense Head changed to Stock In Hand because account Cost of Goods
Sold is not linked to warehouse Stores or it is not the default
inventory account."
The message is purely informational, provides no actionable guidance,
and confuses users who deliberately enable Update Stock. The underlying
account substitution logic is unchanged; only the popup is suppressed.
The two other `msgprint` calls (for the Purchase-Receipt-linked and
no-Purchase-Receipt flows) are intentionally preserved — those surface
a genuine change in behaviour that users may not expect.
Fixes: https://github.com/frappe/erpnext/issues/...
(cherry picked from commit 224dff32df)
# Conflicts:
# erpnext/accounts/doctype/purchase_invoice/services/expense_account.py
fix(bom): fetch routing operations when routing is selected
frm.doc.operations is always an array in Frappe, so !frm.doc.operations
was always false (empty array [] is truthy in JS), causing get_routing()
to never fire when a Routing is selected on a BOM with no existing
operations.
Changed the guard to !frm.doc.operations.length so the fetch triggers
correctly when the operations table is empty.
Also wired the same fetch into the with_operations handler so that
enabling the checkbox after a Routing is already set will populate
operations without requiring the user to re-select the Routing.
Co-authored-by: Umair Sayed <umairsayed@Umairs-MacBook-Air-2.local>
(cherry picked from commit 9249fa89aa)
`parent_items` already comes from the disabled-filtered parent query,
and on v16 an item has at most one bundle, so the child query cannot
reach a disabled bundle.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On version-16-hotfix, Product Bundle has no `is_active` field and is not
submittable (docstatus is always 0), so the backported queries crashed
with "Unknown column 'is_active'" and would otherwise have matched no
rows. Keep v16's `docstatus: 0` and derive activity from `disabled`, as
the surrounding build_row calls already do.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Partial backport of frappe/erpnext#55791 to version-16-hotfix. On v16,
Product Bundle is neither submittable nor versioned and every resolution
path (packing, POS, item details, selling controller) already filters
`disabled: 0`, so only the user-facing gaps are backported:
- the "Get Items from Product Bundle" dialog no longer offers disabled
bundles
- list view indicator: Disabled (grey) / Active (green)
- Product Bundle Balance report excludes disabled bundles
- `disabled` field gets a description, standard filter and no_copy (a
copied bundle starts enabled)
The develop-only parts (un-deprecating the field, `is_active`/docstatus
handling, the version picker filter and the disabled-version validation
on transaction rows) have no v16 equivalent and are intentionally
dropped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stock Ageing iterates stock ledger entries through an unbuffered
(streaming) cursor. _get_batchwise_valuation() lazily queried
Batch.use_batchwise_valuation from inside that loop whenever a row
carried the legacy batch_no field, and the nested query invalidated
the active streaming result set — crashing the report (or silently
dropping the remaining rows, depending on the driver version).
Resolve the valuation flags in a single query before entering the
unbuffered cursor block; the lazy lookup now only serves callers that
pass stock ledger entries in directly, where no streaming is active.
Fixes https://github.com/frappe/erpnext/issues/55786
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 060a5c4eeb)
Co-authored-by: Diptanil Saha <diptanil@frappe.io>
fix(process statement of accounts): validate pdf_name and validate permission before triggering send_auto_email (#55781)