Commit Graph

60494 Commits

Author SHA1 Message Date
Mihir Kandoi
44fdf7bea9 fix: keep the bulk supplier field to half the supplier selection dialog
A lone Link field stretched the full width of the dialog, which reads as a
search bar rather than a field. A column break holds it to half.
2026-08-01 09:21:16 +05:30
Mihir Kandoi
e84bf44e51 feat: set one supplier across every item in the supplier selection dialog
A Material Request where few items carry a default supplier meant picking the
same supplier row by row. A Supplier field above the table copies its value
into every row, leaving the exceptions to be corrected by hand.

Both pickers skip suppliers that are disabled or barred from Purchase Orders by
their scorecard standing.
2026-08-01 09:19:49 +05:30
Mihir Kandoi
f0bb70539d fix: warn about existing draft orders before the supplier selection creates more
Creating through the dialog calls the endpoint directly instead of going
through open_mapped_doc, so the draft link guard that every other Create action
runs never fired, and a repeated dialog quietly produced a second set of draft
orders for the same quantity.
2026-08-01 09:16:13 +05:30
Mihir Kandoi
8ffe5ba420 test: reject the same Material Request item twice in one supplier selection 2026-08-01 09:11:37 +05:30
Mihir Kandoi
99d56cc850 fix: reject the same Material Request item twice in one supplier selection
Each row was checked against the pending quantity on its own, so a payload that
listed one item under two suppliers passed both checks and ordered the pending
quantity twice. The dialog cannot produce that, a direct call to the endpoint
can.
2026-08-01 09:11:37 +05:30
Mihir Kandoi
21c6d10ad3 fix: escape item code and UOM in the supplier dialog errors
Desk renders a client side message as HTML, so an Item or UOM whose name holds
markup ran as markup in the buyer's session.
2026-08-01 09:11:37 +05:30
Mihir Kandoi
3856eaa35e fix: open the Purchase Order when the supplier selection creates only one
Naming a single order in a message and leaving the buyer to click it is a step
for nothing. The form opens directly when there is one order; the message stays
for the case it was meant for, several orders at once.
2026-08-01 09:02:05 +05:30
Mihir Kandoi
d233fdf198 test: reject a supplier selection without items 2026-08-01 09:00:12 +05:30
Mihir Kandoi
07445b3675 feat: order only the items ticked in the supplier selection dialog
Every row is ticked when the dialog opens, so the common case of ordering
everything is unchanged, and a buyer who wants a partial order unticks what
should wait. Creating with nothing ticked is rejected.
2026-08-01 09:00:12 +05:30
Mihir Kandoi
5a78e2290a fix: link the item and spell out the unit in the supplier dialog errors
A bare item code left the buyer to find the item themselves, and a bare number
gave no clue what the limit was counted in. Both messages now link the item and
state the pending quantity in bold with its UOM.
2026-08-01 08:57:04 +05:30
Mihir Kandoi
671c289303 test: alert when Required By falls back to today 2026-08-01 08:52:23 +05:30
Mihir Kandoi
53e09dfdd6 feat: alert when Required By falls back to today
Items whose requested date has passed silently got today as Required By, which
is a date the buyer never asked for. A toast now says so.
2026-08-01 08:52:23 +05:30
Mihir Kandoi
d0cae2eb9c feat: show the UOM alongside the quantity in the supplier selection dialog
The quantity is meaningless without the unit it is counted in, which the buyer
had to look up on the Material Request itself.
2026-08-01 08:52:23 +05:30
Mihir Kandoi
6f22551aae fix: list the Purchase Orders created per supplier instead of opening one
Opening one of several created orders hid the rest and moved the buyer off the
Material Request. The created orders are now reported the way Production Plan
reports its documents, as links in a message, and the form stays put.
2026-08-01 08:39:03 +05:30
Mihir Kandoi
15d10bbaf1 test: Required By on Purchase Orders created per supplier
Backdates the Material Request item so the mapper drops its schedule date, and
asserts the created order still saves with today as Required By.
2026-08-01 08:38:42 +05:30
Mihir Kandoi
d05bd80b1e fix: set Required By on Purchase Orders created per supplier
Mapping drops a schedule date that already passed, leaving the buyer to pick a
new one on the Purchase Order form. Nothing fills it in when the orders are
created straight from the supplier selection dialog, so a Material Request
whose required date has gone by failed to save with "Please enter the Required
By".

Items that lose their date now fall back to today, which is the earliest date a
Purchase Order raised today accepts.
2026-08-01 08:38:26 +05:30
Mihir Kandoi
09cfd1fe91 test: quantity handling in the supplier selection dialog
Asserts the requested quantity reaches the Purchase Order item and that rows
without a supplier, or with a quantity that is zero, negative or beyond the
pending quantity, are rejected.
2026-08-01 08:38:15 +05:30
Mihir Kandoi
da83370c5c feat: adjust the ordered quantity in the supplier selection dialog
The dialog prefilled the pending quantity of each Material Request item but
kept it read only, so ordering less than what was requested meant editing the
Purchase Order afterwards.

The quantity is now editable and is validated against the pending quantity of
its Material Request item, both in the dialog and on the server. The requested
quantity is handed to the mapper as the pending quantity of the source row, so
the existing mapping - including the subcontracting conversions - derives the
Purchase Order quantities from it unchanged.
2026-08-01 08:38:10 +05:30
Mihir Kandoi
65be201ed6 test: supplier selection when creating Purchase Orders from Material Request
Covers the default supplier lookup for pending items, the supplier passed
through to a single mapped order, the grouping of items into one order per
supplier, and the failure when an item is sent without a supplier.
2026-07-31 22:22:55 +05:30
Mihir Kandoi
e8df7b4a90 feat: select a supplier per item when creating Purchase Orders from Material Request
Creating a Purchase Order from a Material Request mapped every pending item
into a single order, leaving the buyer to split it by hand whenever the items
came from different vendors.

The Create action now reads the default supplier of each pending item (item,
item group, then brand defaults). When the items resolve to more than one
distinct supplier - including the case where only some of them have a default -
a dialog lists the items with their default supplier prefilled and editable.
Submitting it groups the items by the chosen supplier and creates one draft
Purchase Order per group.

When every item resolves to the same supplier the order is mapped straight
away with that supplier set, and when none of them has a default supplier the
previous behaviour is unchanged.
2026-07-31 22:22:49 +05:30
Jatin3128
7febc28ed6 feat: auto-fill subscription accounting dimensions from plan with item fallback (#57615)
When a plan is selected in the Subscription's Plans table, the Subscription's
accounting dimensions (cost center and any custom dimensions) auto-fill from the
plan, falling back to the plan item's company default (selling cost center for a
Customer, buying for a Supplier). Only empty fields are filled. Stale async
responses are ignored so a quick re-pick of the plan can't be overwritten.
2026-07-30 15:07:15 +05:30
Shllokkk
956105579d Merge pull request #57618 from Shllokkk/asset-manual-create-valuation-rate
fix: source manually created asset value from valuation rate
2026-07-30 14:52:50 +05:30
Shllokkk
46e01c2d92 fix: source manually created asset value from valuation rate 2026-07-30 14:25:41 +05:30
Mihir Kandoi
e65e1d3c96 Merge pull request #57616 from mihir-kandoi/fix/item-group-root-seeding
fix: seed standard Item Groups under the existing tree root
2026-07-30 13:24:52 +05:30
Mihir Kandoi
e7088d8981 fix: seed standard Item Groups under the existing tree root
install_fixtures always inserted "All Item Groups" as a parentless group.
On a site where another app had already created the root, ItemGroup.validate
re-parented it, leaving a second group-root that held the standard groups
while the real root held everything else.

This is reproducible with the healthcare app on a non-English site: its
after_install seeds the root as _("All Item Groups"), so a pt-BR site gets
"Todos os Grupos de Itens" as the root before the setup wizard runs. The
split predates #57390 -- the old translated-name lookup resolved to the same
root and produced an identical tree.

Resolve the root once with get_root_of (falling back to the canonical English
name on fresh installs) and use it for the root record's exists-guard and the
standard groups' parent, matching Company.create_default_departments.

Patch merges an already-seeded "All Item Groups" into the root it sits under,
lifting its children and repointing every link.

Closes #57581
2026-07-30 13:08:28 +05:30
Soham Kulkarni
ec02b5fa64 Merge pull request #57614 from sokumon/item-default
fix: unchecking default workspace
2026-07-30 12:39:16 +05:30
sokumon
85fa6596b8 fix: unchecking default workspace 2026-07-30 12:23:00 +05:30
Mihir Kandoi
0a7c8504e6 Merge pull request #57609 from mihir-kandoi/fix/title-field-parity
fix(projects): read the Timesheet label from the employee field
2026-07-30 08:36:31 +05:30
Mihir Kandoi
38e5674ea4 chore(stock): drop the dead title template on Material Request
`set_title()` runs in validate and always fills `title` first, so
`set_title_field()` never renders `{material_request_type}`, and
create_new.js skips defaults for the field `title_field` names. Titles
stay "<type> Request for <items>".
2026-07-30 08:22:01 +05:30
Mihir Kandoi
03d84430b6 fix(projects): read the Timesheet label from the employee field
Timesheet was the only doctype where the {...} template on `title`
actually rendered: `title_field` was `title`, so `set_title_field()`
seeded it from `{employee_name}` on insert. A `default` renders once, so
reassigning a draft left the stored title — and every label derived from
it — on the previous employee, with no way to correct it from the form
because the field is hidden.

Point `title_field` at `employee_name` so the label reads the live field
instead of a copy that drifts. Existing rows need no backfill.
2026-07-30 08:22:00 +05:30
Mihir Kandoi
f71946def7 Merge pull request #57419 from kaulith/fix/update-items-row-removal-permission
fix: don't require cancel and delete perms to remove items via Update Items
2026-07-29 16:42:26 +05:30
Khushi Rawat
4f1adb8a94 Merge pull request #57520 from khushi8112/feature/default-modern-print-formats
feat: default new sites to the Modern with Images print formats
2026-07-29 15:47:08 +05:30
Jatin3128
cfe18e8427 fix: let Purchase Receipt cancel defer to Frappe's linked-document check (#57592)
on_cancel pre-blocked cancellation with its own "Purchase Invoice is
already submitted" guard, duplicating the check Frappe already runs for any
submitted linked document. Drop the guard and the unused check_next_docstatus()
method it mirrored so the receipt defers to the framework: the Cancel All
Documents flow cancels the invoice first and then the receipt, and a direct
cancel is still rejected by Frappe's linked-document check.

Add a regression test that a direct cancel of a receipt with a submitted
invoice is rejected and rolls back, leaving no stray stock or GL entries.
2026-07-29 14:44:32 +05:30
Jatin3128
6b8b9d3644 test: isolate accounts settings mutation in overdue threshold test (#57441)
* test: isolate accounts settings mutation in overdue threshold test

test_overdue_billing_threshold_on_submit mutated the Accounts Settings singleton
without restoring it, so a failed assertion mid-test leaked
enable_overdue_billing_threshold and the bypass role into later tests that submit
sales invoices. Wrap the mutations in try/finally and restore the originals. Also
assert that a 0 overdue limit on the customer inherits the customer group's limit.

* test: restore credit limits in overdue threshold fallback test
2026-07-29 12:38:33 +05:30
Nabin Hait
b86ad21444 Merge pull request #57314 from krishna-254/fix/skip-italy-einvoice-opening-invoices
fix(italy): skip e-invoicing for opening invoices
2026-07-29 11:08:59 +05:30
Diptanil Saha
372dff2ffa refactor(accounts): repost accounting ledger (#56442)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 22:51:06 +00:00
Vishnu Priya Baskaran
5125d64b7f fix: clear deferred revenue/expense fields on uncheck (#57140) 2026-07-29 04:18:45 +05:30
Krishna Pramod Shirsath
e0c31f1745 fix: recover failed POS closings (#57203)
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: diptanilsaha <diptanil@frappe.io>
2026-07-28 22:29:47 +05:30
Mihir Kandoi
6d748c5523 Merge pull request #57571 from mihir-kandoi/move-warehouse-defaults-to-company
refactor: move warehouse defaults from Stock Settings to Company
2026-07-28 20:28:55 +05:30
Mihir Kandoi
2095073688 fix: check company permission before reading sample retention stock
validate_sample_quantity and move_sample_to_retention_warehouse are
whitelisted and take company from the caller, which selects whose retention
warehouse gets read. The retained batch qty then reaches the return value and
the max-retained warning, so an authenticated user could probe another
company's stock with a known item and batch.

Gate the shared company -> warehouse resolution on read permission for the
Company, which respects User Permissions. validate_sample_quantity only grew
a company argument in this branch; move_sample_to_retention_warehouse already
took one, so this closes that path too.
2026-07-28 20:15:19 +05:30
Mihir Kandoi
ac477bb33c test: stop relying on companies having no default warehouse
Companies now get their Stores warehouse as Default Warehouse, so item
warehouse resolution succeeds where it previously came back empty.

test_internal_pr_reference cleared inter_company_reference and asserted a
ValidationError, but no validation covers that field - the mapper already
sets it. It was incidentally catching 'Row #1: Warehouse is mandatory for
stock Item' from the blank target warehouse, so the assertion never tested
what it claimed. Dropped it; the delivery_note_item assertion below still
covers the reference linkage.

test_inter_company_transaction_without_default_warehouse now establishes its
own premise by clearing the company's default warehouse instead of relying
on it being unset. Its failure previously skipped the teardown that restores
frappe.local.enable_perpetual_inventory, which db rollback cannot undo, which
in turn broke two later inter-company tests.
2026-07-28 20:06:47 +05:30
Mihir Kandoi
455251abe1 fix: throw when the transaction company has no sample retention warehouse
Item.retain_sample is validated against any company having one configured,
since Item is not company-scoped. The transaction company may still not be,
in which case get_batch_qty received warehouse=None and returned its batch
list, which was then compared numerically -> TypeError.

Resolve company -> retention warehouse through one helper that throws a
clear message instead, covering both the sample stock entry and the
whitelisted quantity validation.
2026-07-28 19:41:29 +05:30
Mihir Kandoi
26613d258e refactor: move warehouse defaults from Stock Settings to Company
Default Warehouse and Sample Retention Warehouse were global singles, so every
consumer had to re-check that the warehouse belonged to the transaction's
company before using it. Both now live on Company, under a new Warehouse
Defaults section that also collects the warehouse fields Company already had.

The company check moves to Company.validate_warehouses, which also rejects
group warehouses for all seven fields — a group or cross-company value there
already failed at SLE time, this just surfaces it at the source.

New companies get their Stores warehouse as Default Warehouse via
create_default_warehouses, replacing the setup-wizard and test-fixture code
that seeded the global.
2026-07-28 19:29:18 +05:30
Mihir Kandoi
c80a848216 Merge pull request #57567 from aerele/fix/stock-balance-for-none-row
fix: guard against None row in get_stock_balance_for
2026-07-28 19:26:26 +05:30
Shllokkk
3f0b894cdf Merge pull request #57566 from Shllokkk/item-def-accounting-desc
fix(item): correct description on deferred revenue/expense
2026-07-28 19:22:27 +05:30
Shllokkk
fa75aa08ab fix(item): correct description on deferred revenue/expense 2026-07-28 19:00:24 +05:30
R-Jayaraman
f9d25bc3d3 fix: guard against None row in get_stock_balance_for
row defaults to None but was dereferenced unconditionally when computing
the incoming rate for batch-tracked items, causing an AttributeError for
any caller (e.g. direct API calls) that omits row while still passing
batch_no. The other two row accesses in this function already guard
against None; this brings the incoming-rate check in line with them.
2026-07-28 18:57:06 +05:30
Smit Vora
986cea2331 feat: taxable-base resolver hook for custom charge types (#56175) 2026-07-28 17:21:55 +05:30
Mihir Kandoi
0cd95e1995 fix(manufacturing): fall back to UOM Conversion Factor in Production Plan (#57553)
Production Plan read the conversion factor straight off the item's own
UOM child table, so an item with a purchase UOM but no matching row threw
"UOM Conversion factor not found" while Stock Entry silently resolved it
from the item's variant template or the UOM Conversion Factor doctype.
Resolve it the same way, and keep returning None when nothing is
configured anywhere so the missing-setup error still fires.
2026-07-28 11:41:51 +00:00
Shllokkk
5fc20d6b8e fix: respect child warehouse account override in Stock and Account Value Comparison (#57552)
fix: respect child warehouse account override in stock vs account value comparison
2026-07-28 16:51:53 +05:30