* fix: block disabled/frozen customers on Opportunity
Opportunity inherits TransactionBase instead of AccountsController, so
it never ran validate_party_frozen_disabled like Quotation, Sales Order
and Sales Invoice do. A disabled Customer could be saved as an
Opportunity's party and only get caught later at Quotation stage.
Also fixes the party_name Link query on the client: it referenced
erpnext.queries.customer, which was never defined, so disabled
customers showed up in the picker.
(cherry picked from commit 90937ce6d9)
* fix: block disabled/frozen suppliers on Request for Quotation
Request for Quotation overrides validate() entirely and never calls
super().validate(), so it never goes through AccountsController's
party validation. Suppliers also sit in a child table, so the shared
PartyValidator wouldn't have caught it anyway (it only checks a single
top-level party field). A disabled or frozen Supplier could be added
to an RFQ and the RFQ submitted without any warning.
Also filters the suppliers grid's supplier Link field to disabled=0,
matching the same client-side fix applied to Opportunity's party_name.
(cherry picked from commit 4bf65ffc1d)
# Conflicts:
# erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
# erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
* fix: scope Opportunity party validation to Customer only
validate_party_frozen_disabled only enforces Customer/Supplier/Employee,
so passing opportunity_from straight through silently no-op'd for Lead
and Prospect. Made the Customer-only scope explicit instead of relying
on that implicit fallthrough.
Lead.disabled is not enforced anywhere else in the codebase (lead_query,
the picker used for this same field, only filters status/docstatus), so
deliberately not extending validation to Lead-sourced Opportunities.
(cherry picked from commit 8c0a945417)
* refactor: move RFQ supplier disabled filter to link_filters
Static filters with no doc-dependent values belong on the field
definition, not in JS. Matches the existing pattern used for
Warehouse/Item link_filters elsewhere (e.g. job_card_item.json,
product_bundle_item.json).
(cherry picked from commit 6b35c51ff1)
* fix: resolve backport conflicts for disabled/frozen party validation
The automated backport left unresolved merge conflict markers committed
in request_for_quotation.py and test_request_for_quotation.py.
Dropped test_duplicate_supplier_rejected, test_rfq_blocked_for_supplier_with_prevent_rfqs
and test_rfq_status_lifecycle from the conflict resolution, they don't exist on
this branch and aren't part of this backport.
---------
Co-authored-by: Jatin3128 <jatinsarna8@gmail.com>
The inverse (1 / value) and intermediate-UOM branches of
get_uom_conv_factor returned raw float quotients like
0.4535922921968971, bypassing the precision the docfields now declare.
Same for the client-side back-calculation from an edited stock qty.
Round both to the UOM Conversion Factor value precision.
(cherry picked from commit ca5a673409)
The toolbar handlers were copied onto view.events as unbound functions, so
`this` inside them was that object literal rather than the BOMConfigurator.
They worked only because the literal also carried `frm`, and broke as soon as
a handler called a method the literal did not list: get_item_code, added when
the tree started keying nodes on the row name, threw
"this.get_item_code is not a function" and killed Add Raw Material, Add Sub
Assembly and Convert to Sub Assembly.
Assign the instance instead of a hand-maintained whitelist. Every method is
reachable, `this.frm` keeps working, and no future method can be forgotten.
Fixes#57773
(cherry picked from commit 097ce0f348)
Backport of five fixes merged to develop, adapted to this branch, where
the field is still named `type` and the stock entry rate logic has not
been split out of set_basic_rate.
- A secondary row with no BOM link is costed out of the finished good,
as legacy scrap was. Finished goods are rated last so a single
validate pass sees the secondary rows' amounts. (#57732)
- Repack no longer flags secondary rows as finished goods, so each side
takes the share the BOM declares instead of the scrap absorbing the
finished good's percentage. (#57735)
- A BOM allocation of 0% means the row carries no cost, rather than
falling through to the item's own valuation rate. (#57736)
- Secondary Item Type no longer waives a quality inspection on purposes
that do not produce secondary items. (#57737)
- The BOM allocation applies to the consumption entry's cost when the
raw material cost comes from one. (#57738)
Replaces the individual backports, which could not be cherry-picked
cleanly: every hunk needed rewriting against the pre-rename field and
the un-refactored rate logic.
calculate_item_values rounds every Float field on an item row to the
site's Float Precision (3 by default), and conversion_factor was one of
them. The factor is a ratio, not a rate: UOM Conversion Factor.value is
stored at precision 9, and Material Request keeps the full value because
it has no currency field and so never runs the calculation.
Mapping a Material Request to a Purchase Order therefore truncated the
factor - 0.453592292 for Pound -> Kg became 0.454 - and stock_qty, which
is recomputed as qty * conversion_factor, drifted from the quantity that
was requested, leaving the Material Request unable to close.
Exclude conversion_factor from the rounded fields on the server and on
the client. Factors below the site precision would otherwise round to
zero outright.
(cherry picked from commit 269cc6ee3b)
The BOM Creator tree identified a node by the parent's item code
(fg_item) instead of the specific BOM Creator Item row, so every
occurrence of a repeated sub-assembly shared one child set: expanding
any one of them listed the raw materials of all of them, and deleting
one wiped the raw materials of its siblings.
Key the tree on fg_reference_id and make the node value the row name,
matching the framework convention that a tree node's value is its
docname. Item code now travels as its own field for the label and for
the fg_item argument sent back on add/convert.
Fixes#57311
(cherry picked from commit b37152752f)
set_route_options_for_new_doc lived in TransactionController, so doctypes
extending StockController directly (Stock Reconciliation, Stock Entry) missed
the Batch/SABB prefill or duplicated it locally. Move it to StockController
and call it from onload_post_render so all descendants inherit it.
- Batch quick entry from Stock Reconciliation items now prefills Item
- SABB route options unified: warehouse || s_warehouse || t_warehouse,
so transaction doctypes now also prefill warehouse
- Stock Entry's duplicate handler removed; its onload_post_render now
calls super
(cherry picked from commit 551559e804)
fix: show transaction currency symbol in Payment Request schedule dialog and reference table (#57050)
* fix: show transaction currency symbol in Payment Request schedule dialog and reference table
When company currency (INR) differs from customer currency (USD), the Amount
column in the Select Payment Schedule dialog and the Payment Reference table on
the Payment Request form incorrectly displayed the company currency symbol (₹)
instead of the transaction currency symbol ($).
- Pass `currency` from the parent document on each schedule row returned by
`get_available_payment_schedules` so the dialog can resolve the symbol.
- Add a hidden `currency` field to the dialog table and set `options: "currency"`
on `payment_amount` so Frappe renders the correct symbol.
- Propagate `currency` into Payment Reference rows in `set_payment_references`.
- Add a hidden `currency` Link field to the Payment Reference child DocType and
set `options: "currency"` on its `amount` field so the table renders correctly.
* fix: preserve currency when serializing payment schedule rows
get_available_payment_schedules set `schedule.currency` directly on
the Payment Schedule Document row, but `currency` isn't a field on
that DocType, so the API response serializer stripped it before it
reached the client. The Select Payment Schedule dialog and the
Payment Reference table therefore always fell back to the company
currency symbol, even with the earlier options="currency" changes in
place.
Convert each row to a plain dict via as_dict() first, then set the
currency key on the dict so it survives serialization.
* refactor: source schedule currency in dialog instead of API serializer
get_available_payment_schedules had to convert each child row with
as_dict() and re-attach currency, because currency is not a field on
Payment Schedule and the response serializer drops attributes set on the
Document itself.
The schedule dialog already has the transaction currency on frm.doc, so
set it there and let the API keep returning the schedule rows unchanged.
Payment Reference still stores currency per row.
---------
(cherry picked from commit 83e04dd773)
Co-authored-by: Henil Maru <henil@frappe.io>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jatin3128 <jatinsarna8@gmail.com>
Co-authored-by: Jatin3128 <140256508+Jatin3128@users.noreply.github.com>
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.
(cherry picked from commit ab30bab6cb)
- 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
(cherry picked from commit 3ece4a615d)
- Remove `depends_on` restriction from `inspection_required` field so it
is visible for all Stock Entry purposes, not just Manufacture
- Fix `check_item_quality_inspection` to return items for Stock Entry
(was returning [] for unknown doctypes, blocking QI creation flow)
- Fix `inspection_type` in transaction.js to be purpose-aware: Manufacture
and Material Receipt → "Incoming"; all other purposes → "Outgoing"
(cherry picked from commit dceb9a3c6c)
# Conflicts:
# erpnext/stock/doctype/stock_entry/stock_entry.json