Files
erpnext/erpnext/manufacturing
Jatin3128 eeb3cd238e fix(subscription): don't reactivate a cancelled subscription (backport #57774)
* fix(subscription): don't reactivate a cancelled subscription

Backport of #57774 to version-16-hotfix.

set_subscription_status() unconditionally set status to Active once
there was no outstanding invoice, even if the subscription had been
intentionally cancelled. Paying off an invoice issued before
cancellation (directly, or via the Payment Entry -> refresh hook)
flipped a Cancelled subscription back to Active while cancelation_date
stayed set.

process()'s cancel_at_period_end check compared posting_date against
getdate(self.end_date), and getdate(None) returns today, so an empty
end_date was silently treated as "cancel now" on every scheduler run.
Combined with the reactivation bug, this let a cancelled subscription
toggle Cancelled -> Active on each run and generate another invoice at
the next period boundary.

Fixes #57761

* test: fix flaky test_update_bom_cost_in_all_boms via valuation reset

Backport of #56796 to version-16-hotfix.

reset_item_valuation_rate() only reconciled warehouses where the item
currently has positive stock (actual_qty > 0). get_valuation_rate()
averages Sum(stock_value)/Sum(actual_qty) across all of an item's
bins, so a negative balance left over in another warehouse by a prior
test can cancel out the reset qty and collapse the average to 0,
failing the assertion with 0.0 != 10.0.

This branch never got #56796 (it predates the frappe.get_all
refactor of this helper and still uses raw SQL), so applying the same
fix here: reconcile every warehouse with a non-zero balance, not just
positive ones.

* fix(subscription): don't let period rollover defeat cancel_at_period_end

process() can advance current_invoice_end to the next period (via
update_subscription_period(), when generating the current period's
invoice) before the cancel_at_period_end check further down runs. For
a subscription with no end_date, that check now compared posting_date
against the already-rolled-forward current_invoice_end, which is
always in the future, so cancel_at_period_end was silently never
honored.

Snapshot current_invoice_end before any rollover and use that in the
check instead, so it still targets the period that just ended.

Found via review on the version-15-hotfix backport (#57780).

---------

Co-authored-by: test <test@test.com>
2026-08-05 12:23:31 +05:30
..
2026-06-13 13:41:16 +00:00
2013-12-11 10:43:52 +05:30

Plan and manage manufacturing operations, bill of materials for manufacturing.