Company.create_default_warehouses stored warehouse_name through the
session _(), so a site set up in a non-English language keeps its
default warehouses under translated names. The opening-stock fallback
in item.py then looks up {"warehouse_name": _("Stores")} from an
arbitrary session and misses the warehouse whenever the lookup
session's language differs from the creation session's.
Create the default warehouses with canonical English names, matching
the identity-_ convention install_fixtures uses for other default
records. The exists-guard also matches the session translation so a
re-run on a legacy site does not insert English duplicates next to
translated warehouses.
The "Stores" fallback lookup moves to get_stores_warehouse, which
tries the canonical name first and falls back to the session
translation so legacy sites keep resolving their translated warehouse.
The setup-wizard and test-bootstrap lookups drop _() since they now
run after English creation (install_fixtures already used identity _,
so its lookup silently missed translated warehouses before this
change).
Same bug class as #57345.
A name lookup misses roots created under a translated name (pre-#49875
setups) or renamed roots. Resolve the first parentless group by lft and
guard against self-parenting when the root itself is saved.
Native JSON request bodies deliver target_doc as a parsed dict, which the
str | Document type hints rejected, breaking every Get Items From button.
Unify all whitelisted mapper endpoint hints to str | dict | Document | None.
Needs frappe#41190 so get_mapped_doc converts the dict target.
_("All Item Groups") resolves in the session language, so for
non-English users the db.exists lookup missed the root (stored in
English) and new groups were saved parentless, becoming uneditable
second roots.
Closes#57345
Company.create_default_departments named and looked up the root
Department via _("All Departments"), which resolves in the session
language. A site set up in a non-English language stores the root
translated, and a company created later from a session in another
language misses it and inserts a second root, corrupting the tree.
Resolve the root once with get_root_of (falling back to the canonical
English name on fresh installs) and reuse it for the root record, the
exists-guard and the child departments' parent.
Also stop translating lookups of records install_fixtures stores under
English names: Price List "Standard Selling" and Print Headings
"Credit Note" / "Debit Note".
Same class as the root Item Group fix (#57386, issue #57345).
feat(shipping-rule): make cost center optional with company default fallback
Cost Center on Shipping Rule is no longer mandatory. When left blank, the
applied shipping tax row falls back to the company default cost center,
avoiding the 'Cost Center is required for Profit and Loss account' error on
submit. The rule's project is also applied to the tax row.
get_permitted_fieldnames never lists Table fields, so allowed_companies
cannot be asserted through it; the write-reset assertions already cover
that field.
The mt940 library exposes ``transaction_reference`` from the :20: tag,
which is the statement-level reference and identical for every
transaction in a statement. The bank-statement-to-CSV conversion was
using it verbatim, so every imported row ended up with the same
reference, making reconciliation impossible.
Read the per-transaction reference from ``customer_reference`` on the
:61: tag instead. Handle two edge cases:
- **Overflow >16 chars.** When a bank emits a single-line :61: whose
reference exceeds 16 characters, the mt940 regex splits the tail into
``extra_details``. Gate the rejoin to cases where
``customer_reference`` is exactly at the 16-char MT940 cap; below
that, ``extra_details`` is genuine supplementary information and must
not be appended.
- **``NONREF`` sentinel.** The MT940 standard marker for "no customer
reference". Check it against the un-concatenated value so that a
``NONREF`` customer reference with populated ``extra_details`` still
falls back to ``bank_reference`` instead of returning a junk
``NONREFsomething`` value.
Also switch the Description column to ``transaction_details`` (the :86:
tag content) so rows carry their real narrative instead of the mostly
empty :61: supplementary field.
Only the master-manager role of each doctype (Item Manager, Sales Master
Manager, Purchase Master Manager) can view and edit restrict_to_companies
and allowed_companies. Customer reuses its existing level-1 permission
rows; Item and Supplier get a new level-1 row.
test@example.com carries System Manager in the frappe fixtures, so on a
fresh CI site it can read Delivery Note and the lookup legitimately
returns the draft. test1@example.com has no roles, making the
no-permission assertion environment-independent.
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
Meta.get_link_fields rescans the field list on every call; hoisting it
out of the row loop cuts the reference walk on a 100-row invoice from
2.8ms to 0.1ms.
Doctypes marked In Create (GL Entry, Stock Ledger Entry, Bin, ledger
entries) are system-created by definition, so derive their exemption
from meta instead of listing them.
Replace the manually maintained transaction allowlist with a wildcard
validate hook: any doctype carrying a Company link field is checked, so
new doctypes are covered automatically. System-managed doctypes (ledger
entries, reposts, bundles, bins, POS consolidation, bank feeds) are
exempted so cancel, repost and reconciliation of documents created
before a restriction changed keep working; that guarantee is pinned by
a cancel-after-restriction test.
Extend company restriction enforcement to the remaining user-entered
transactions (BOM, Work Order, Job Card, Production Plan, Pick List,
Blanket Order, asset and maintenance documents). Ledger and repost
doctypes stay excluded so cancelling or reposting older documents
keeps working after a restriction changes.
Restrict to Companies only filtered list views and document reads, and
only for users with Company user permissions. Any user could still use
a master restricted to Company A in a Company B transaction, and users
without Company user permissions bypassed the feature entirely.
Validate on save of transactions that every linked Item, Customer and
Supplier allows the transaction company, and filter item link queries
by the transaction company so restricted items don't show up in the
item selector.
frappe.get_list defaults to 20 rows; child-table joins can produce
duplicate parent names that fill the window and hide further drafts.
Also clarify the check-ordering regression test.
get_single_value inside _revalue_reconciled_batch_slots runs while
rows stream through the unbuffered cursor on MariaDB, killing the
active iterator. Resolve it once in generate() with the other
prefetches.