Commit Graph

58564 Commits

Author SHA1 Message Date
Raffael Meyer
8d69dbd4ef fix: error message wording (#57495)
(cherry picked from commit bdf586c670)
2026-07-27 11:16:01 +00:00
mergify[bot]
ad9870acc1 fix(crm): align Opportunity status checks with Quotation statuses (backport #57489) (#57491)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2026-07-27 12:22:35 +02:00
Mihir Kandoi
8925585895 Merge pull request #57481 from frappe/mergify/bp/version-16-hotfix/pr-57463
fix(subcontracting): release raw-material reservation when closing a subcontracting order (backport #57463)
2026-07-27 15:01:03 +05:30
Mihir Kandoi
8d511c9b71 Merge pull request #57487 from frappe/mergify/bp/version-16-hotfix/pr-57485
fix: pool batch slot values on every run, not only when negative (backport #57485)
2026-07-27 14:04:17 +05:30
Mihir Kandoi
85925680ac test: assert batch pooling preserves the group total on a repeating rate
(cherry picked from commit 545262c5d4)
2026-07-27 08:24:15 +00:00
Mihir Kandoi
5763378ee1 fix: pool batch slot values on every run, not only when negative
A batch is one valuation pool, so any per-slot value difference within a
batch is stale detail from the report's own age slots, not real valuation.
The rebalance only ran when consumption had already driven a slot negative,
so a batch whose receipts landed at different rates kept a skewed split
across age buckets (one bucket free, another double-priced) while the total
stayed correct.

Drop the negative-slot precondition and always spread a batch's pooled value
over its slots in proportion to qty. Redistribution preserves group totals,
so buckets still sum to Stock Balance; only the split across ages changes.

(cherry picked from commit cedaaa3a00)
2026-07-27 08:24:15 +00:00
Lakshit Jain
c3eac77ee1 Merge pull request #56952 from frappe/mergify/bp/version-16-hotfix/pr-54855
refactor(financial-report): fix row transformation for growth calculations (backport #54855)
2026-07-27 13:31:55 +05:30
Sudharsanan11
008c3b145d test(subcontracting): cover reservation release on closing a subcontracting order
close a partially-received sco with a reserve warehouse and assert the
raw-material reservation is released and projected qty recovers.

(cherry picked from commit e4b8065a69)
2026-07-27 13:01:24 +05:30
Sudharsanan11
ee75fac9d7 fix(subcontracting): release raw-material reservation when closing a subcontracting order
the bin reserved-qty recalc filtered out closed purchase orders but not
closed subcontracting orders, so closing a partially-received sco kept the
reservation for the unreceived qty and left projected qty understated.
apply the same closed-status filter to the subcontracting order path.

(cherry picked from commit db91a79d31)

# Conflicts:
#	erpnext/stock/doctype/bin/bin.py
2026-07-27 13:01:24 +05:30
ruthra kumar
220d005cc2 Merge pull request #57478 from frappe/mergify/bp/version-16-hotfix/pr-57476
refactor: configurable date in reverse ERR journals (backport #57476)
2026-07-27 12:34:16 +05:30
ruthra kumar
ed1a58aa2a ci: debugging 2026-07-27 12:23:33 +05:30
ruthra kumar
2fd1dbd23a refactor(test): manually submit reverse err journal
(cherry picked from commit 1a558ce641)

# Conflicts:
#	erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py
2026-07-27 11:53:29 +05:30
ruthra kumar
68dcc96527 refactor: configurable date in reverse ERR journals
(cherry picked from commit 0be33e4132)
2026-07-27 06:11:10 +00:00
Shllokkk
708d889036 Merge pull request #57473 from frappe/mergify/bp/version-16-hotfix/pr-57443
fix: rename misleading filter labels in AR/AP reports (backport #57443)
2026-07-26 20:22:08 +05:30
Shllokkk
20e2728037 chore: resolve patches.txt conflict for backport 2026-07-26 19:21:01 +05:30
MochaMind
2359e1610a chore: update POT file (#57470) 2026-07-26 15:45:55 +02:00
Shllokkk
2e5fc38179 fix: migrate stored AR/AP ageing filter to renamed field
(cherry picked from commit f13cd00494)

# Conflicts:
#	erpnext/patches.txt
2026-07-26 11:47:26 +00:00
Shllokkk
6d856fa632 fix: rename misleading filter labels in AR/AP reports
(cherry picked from commit e99425b7c4)
2026-07-26 11:47:26 +00:00
Shllokkk
1802c75ed6 Merge pull request #57468 from frappe/mergify/bp/version-16-hotfix/pr-57466
fix: recalculate operating cost on hour rate change in routing (backport #57466)
2026-07-26 16:27:11 +05:30
Shllokkk
c182b4085b fix: recalculate operating cost on hour rate change in routing
(cherry picked from commit 598f6f0f4e)
2026-07-26 08:37:06 +00:00
mergify[bot]
a0af717234 fix: enable the 'Include Zero Stock Items' filter by default to show zero-stock items in the Stock Balance report (backport #57458) (#57460)
fix: enable the 'Include Zero Stock Items' filter by default to show zero-stock items in the Stock Balance report (#57458)

(cherry picked from commit 4e8f5de5cb)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2026-07-25 08:27:06 +05:30
Jatin3128
d3c5e866f0 feat: block sales invoice submit when customer overdue exceeds threshold (backport #57230, #57298) (#57438)
* feat: block sales invoice submit when customer overdue exceeds threshold (#57230)

* feat: block sales invoice submit when customer overdue exceeds threshold

Adds an opt-in, per-customer Overdue Billing Threshold. When enabled in
Accounts Settings, submitting a Sales Invoice is blocked if the customer's
overdue amount exceeds their threshold, unless the current user holds a
configured bypass role. Modeled on the existing credit limit feature.

- Accounts Settings (Credit Limits tab): enable toggle + bypass role.
- Per-customer threshold on the Customer Credit Limit table, shown only
  when the feature is enabled via a property setter (same mechanism as
  subscription / accounting dimension sections). Table relabeled to
  "Credit & Overdue Limits".
- Overdue is read live from the ledger via get_outstanding_invoices
  (payments already netted), summing Sales Invoices past their due date.
- Enforced in Sales Invoice on_submit, after the credit-limit check;
  returns are exempt.
- validate_credit_limit_on_change no longer trips when a row sets only
  the overdue threshold (credit_limit = 0).

Fixes #52960

* fix: compute overdue amount in company currency and format with fmt_money

get_customer_overdue_amount now sums GL Entry debit - credit grouped per
invoice, which is always booked in company currency, instead of using
get_outstanding_invoices which returns the receivable-account currency.
The threshold is in company currency, so the previous comparison could mix
currencies for customers with a foreign-currency receivable account. This
mirrors how get_customer_outstanding computes the figure for the existing
credit-limit check.

The blocking message now formats both amounts with fmt_money using the
company currency.

Adds a test asserting a 100 USD invoice at a conversion rate of 50 is
counted as 5000 in company currency.

* refactor: drop redundant threshold coercion and dead test cleanup

- Coerce the overdue threshold with flt() once when reading it, instead of
  calling flt() on it at each of the three use sites.
- Remove a no-op set_overdue_billing_threshold() call in the feature-disabled
  block (the threshold was already set to that value) and the trailing reset,
  which is dead since each test is rolled back.

No behaviour change.

* fix: compute overdue amount from payment terms, matching the Overdue status

The overdue amount keyed on Sales Invoice.due_date, which set_due_date() sets
to the LAST payment term. An invoice whose first term was past due and unpaid
was therefore counted as zero, even though ERPNext already shows it as Overdue
in the invoice list. The gate and the UI could disagree.

get_customer_overdue_amount now follows the same rule as is_overdue(): per
invoice, the amount that has fallen due (sum of payment schedule terms past
their due date) minus what has been paid, clamped to the outstanding balance.
Invoices without a schedule (POS, opening) still fall back to the invoice due
date, mirroring is_overdue()'s own guard.

The ledger stays the source of truth for what is unpaid: the outstanding per
invoice is still SUM(debit) - SUM(credit) from GL Entry. base_payment_amount is
always stored in company currency, so no currency conversion is needed and the
comparison against the threshold stays consistent.

Adds a test covering a two-term invoice: only the past-due term counts, and
paying it off clears the overdue amount.

* feat: honour the overdue billing threshold set on the customer group

The threshold lives on Customer Credit Limit, which is also rendered on
Customer Group. A threshold set there was stored but never evaluated, so the
configuration was a silent no-op.

get_overdue_billing_threshold now reads the customer's row and falls back to
its customer group, mirroring get_credit_limit. The group's
bypass_credit_limit_check is deliberately not consulted: it is labelled for the
credit limit check at sales order and is unrelated to overdue billing.

get_customer_group_details also dropped the threshold when copying group rows
onto a customer, because it copied a single hardcoded field per table. It now
copies a list of fields per table, so credit_limit and overdue_billing_threshold
both carry over.

* refactor: clearer labels for the overdue billing control (#57298)

refactor: clearer labels and messages, drop "threshold" wording

User-facing text only, no field or behaviour changes:

- Accounts Settings toggle label -> "Restrict Customer Over Billing".
- Bypass role label -> "Role Allowed to Bypass Over Billing Restriction".
- Customer Credit Limit field label -> "Overdue Limit".
- Rewrote the descriptions and the block message to match and to stop
  saying "threshold".

* fix: treat zero overdue limit as opt-out and isolate settings in test

get_overdue_billing_threshold treated an explicit 0 on the customer's credit
limit row as "not set" and fell back to the customer group. A customer could
not be exempted from the group restriction while keeping a credit limit row,
and every existing row defaults to 0, so enabling the feature on a group blocked
all its customers that had any credit limit row. Guard the group fallback on
"threshold is None" (no row for the company) instead of a falsy check, so an
explicit 0 acts as an opt-out.

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.

* fix: let a zero customer overdue limit inherit the group's limit

A 0 on the customer's credit limit row falls back to the customer group again;
only a non-zero value on the customer overrides the group. Reverts the earlier
opt-out interpretation and updates the fallback test to expect the group's limit.
2026-07-24 15:33:26 +05:30
Mihir Kandoi
2b8b6a09dd Merge pull request #57440 from frappe/mergify/bp/version-16-hotfix/pr-57435
fix(accounts): respect user permissions in party dashboard company list (backport #57435)
2026-07-24 15:12:35 +05:30
pandiyan
c79f2e45a8 fix: respect user permissions in party dashboard company list
use frappe.get_list instead of frappe.get_all in get_dashboard_info so
the company list honors user permissions. previously, a party with
invoices across multiple companies would raise "User don't have
permissions to select/read this account" for users restricted to a
subset of companies, since get_party_account was called for companies
the user could not access.

fixes frappe/erpnext#57428

(cherry picked from commit 903c87bcaa)
2026-07-24 09:30:41 +00:00
Mihir Kandoi
ab4b5abb91 Merge pull request #57420 from aerele/backport-57412-customer-pick-list-v16
fix: map pick list customer to delivery note when no sales order
2026-07-24 14:58:23 +05:30
pandiyan
3f6501b4ff fix: map pick list customer to delivery note when no sales order
backport of #57412
2026-07-24 11:12:17 +05:30
Mihir Kandoi
2206e9fe2a Merge pull request #57415 from frappe/mergify/bp/version-16-hotfix/pr-57413
fix: typeerror in get_batches_by_oldest for mixed batch expiry (backport #57413)
2026-07-23 18:38:47 +05:30
pandiyan
bbe7580c9d fix: typeerror in get_batches_by_oldest for mixed batch expiry
sort on (expiry is none, expiry) so a null expiry_date is never
order-compared against a datetime.date, which raised typeerror in
python 3 when a warehouse held both dated and never-expiring batches.

(cherry picked from commit 62c9f8ee3e)
2026-07-23 12:53:51 +00:00
Mihir Kandoi
ef21a9ba9b Merge pull request #57250 from frappe/mergify/bp/version-16-hotfix/pr-57245 2026-07-23 16:25:43 +05:30
Mihir Kandoi
88f9039d1a Merge pull request #57408 from frappe/mergify/bp/version-16-hotfix/pr-57400
fix: guard against missing is_your_company_address custom field on ad… (backport #57400)
2026-07-23 16:21:06 +05:30
pandiyan
2e6b4b5838 fix: guard against missing is_your_company_address custom field on address
(cherry picked from commit ea3ed8b836)
2026-07-23 10:41:18 +00:00
Mihir Kandoi
85d793b690 Merge pull request #57404 from mihir-kandoi/fix-stock-ageing-batch-pool-rebalance-v16
fix: rebalance batch slot values at the pooled rate when driven negative (backport #57403)
2026-07-23 16:09:11 +05:30
Mihir Kandoi
8a50572786 fix: rebalance batch slot values at the pooled rate when driven negative
A batch is one valuation pool, so consumption is valued at the pooled
rate while slots may carry stale intra-batch detail (e.g. units
reconciled at zero and later merged). Consuming such a slot leaves a
negative value on positive qty. Spread the pool value across the
batch's slots when that happens; non-batchwise slots pool per
warehouse.
2026-07-23 15:57:13 +05:30
mergify[bot]
bbd942c600 feat: make Shipping Rule Cost Center optional with company default fallback (backport #57355) (#57385)
feat: make Shipping Rule Cost Center optional with company default fallback (#57355)

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.

(cherry picked from commit a47f25896b)

Co-authored-by: Jatin3128 <140256508+Jatin3128@users.noreply.github.com>
2026-07-23 15:42:28 +05:30
mergify[bot]
84813d7f46 fix: Incorrect creation time at the time cancelling an entry causing an issue especially same posting datetime (backport #57380) (#57397)
* fix: Incorrect creation time at the time cancelling an entry causing an issue especially same posting datetime  (#57380)

* fix: shift same-timestamp sibling SLEs when cancelling an entry

update_qty_in_future_sle compared against the reversal SLE's own
creation and skipped same-posting_datetime siblings on cancel, leaving
their qty_after_transaction stale and causing false negative stock
errors.

* fix: revert update_qty_in_future_sle cancel tie-break, it double-counted

(cherry picked from commit 8c0ec3c179)

# Conflicts:
#	erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py

* chore: fix conflicts

Fix test case for cancelling stock ledger entries with the same timestamp to ensure correct behavior.

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2026-07-23 10:08:20 +00:00
Shllokkk
1132eb1a0f fix: respect selected BOM when creating work order for variant item (#57359)
* fix: respect selected BOM when creating work order for variant item

* fix: add type hints to make_work_order
2026-07-23 13:48:45 +05:30
kaulith
2323f2c978 Merge branch 'version-16-hotfix' into mergify/bp/version-16-hotfix/pr-57245 2026-07-23 11:59:44 +05:30
Mihir Kandoi
e277647f7b Merge pull request #57362 from frappe/mergify/bp/version-16-hotfix/pr-57361
refactor: move new-doc route options to StockController (backport #57361)
2026-07-22 18:04:50 +05:30
Mihir Kandoi
c587f4934a refactor: move new-doc route options to StockController
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)
2026-07-22 12:33:46 +00:00
Mihir Kandoi
e0020b478a Merge pull request #57354 from mihir-kandoi/fix/reserved-batch-precision-v16
fix: get reserved batch qty precision from settings (v16)
2026-07-22 15:11:23 +05:30
Mihir Kandoi
95de2374ed fix: get reserved batch qty precision from settings 2026-07-22 14:58:11 +05:30
mergify[bot]
2c8c076f6e fix(payments): ensure payments app installed on the site in payment_app_import_guard (backport #57342) (#57344)
Co-authored-by: Diptanil Saha <diptanil@frappe.io>
2026-07-21 23:12:53 +00:00
mergify[bot]
a0ac2a58dd chore: remove apiclient (backport #57339) (#57341)
Co-authored-by: Diptanil Saha <diptanil@frappe.io>
2026-07-21 20:26:20 +00:00
Shllokkk
5930ce623c Merge pull request #57321 from Shllokkk/sync-process-loss-percentage-v16
fix: sync process loss percentage when fg qty changes
2026-07-21 16:24:52 +05:30
Mihir Kandoi
3a196ae8e7 Merge pull request #57317 from mihir-kandoi/fix-stock-ageing-reco-revaluation-v16
fix: rescale stock ageing FIFO slot values on stock reconciliation (backport #57316)
2026-07-21 15:46:22 +05:30
Shllokkk
beeffee8f9 fix: sync process loss percentage when fg qty changes 2026-07-21 15:11:10 +05:30
Mihir Kandoi
0f252542c3 fix: resolve float precision before streaming stock ledger entries
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.
2026-07-21 14:34:12 +05:30
Mihir Kandoi
92217b2c45 fix: use system float precision for batch qty comparison 2026-07-21 14:18:24 +05:30
Mihir Kandoi
a4bf50656a fix: revalue batch reco slots only when the entry covers the full batch
stock_value_difference / qty equals the new batch rate only when the
reco entry carries the entire batch, as the split out/in reco SLEs and
batches reconciled from zero do. Partial direct-batch_no entries mix a
qty delta with existing stock, so their slots keep prior values.

Plain items need no such guard: the valuation engine collapses the
FIFO stack to qty_after * valuation_rate on every reconciliation, so
rescaling remaining slots at the reco rate matches the ledger. Lock
that with a test.
2026-07-21 14:09:33 +05:30
Mihir Kandoi
6b3b03fcd8 fix: rescale batch FIFO slot values on stock reconciliation
Batch items take the batch-slot path, which mirrors the same value
arithmetic: the reco's incoming entry dumps the revaluation remainder
on one slot. Rescale each reconciled batch's slots at its post-reco
rate (stock_value_difference / qty of the incoming bundle entry).
2026-07-21 13:49:41 +05:30