From 6e6263dc5aafc6847bfe32e28ef75b1c030f303a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 3 Jul 2026 14:08:20 +0530 Subject: [PATCH] fix: bill all months across a year boundary in Monthly Rate plans (cherry picked from commit 196730c53563f2fdcfe62df21c1718f15f59e2e0) --- .../doctype/subscription_plan/subscription_plan.py | 4 +++- .../subscription_plan/test_subscription_plan.py | 10 ++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py index cdfa3e56d9f..5debeccb95c 100644 --- a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py +++ b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py @@ -72,7 +72,9 @@ def get_plan_rate( start_date = getdate(start_date) end_date = getdate(end_date) - no_of_months = relativedelta.relativedelta(end_date, start_date).months + 1 + delta = relativedelta.relativedelta(end_date, start_date) + # include the years component so cross-year spans aren't under-counted + no_of_months = delta.years * 12 + delta.months + 1 cost = plan.cost * no_of_months # Adjust cost if start or end date is not month start or end diff --git a/erpnext/accounts/doctype/subscription_plan/test_subscription_plan.py b/erpnext/accounts/doctype/subscription_plan/test_subscription_plan.py index 24548e3009b..62d5b40706a 100644 --- a/erpnext/accounts/doctype/subscription_plan/test_subscription_plan.py +++ b/erpnext/accounts/doctype/subscription_plan/test_subscription_plan.py @@ -46,12 +46,10 @@ class TestSubscriptionPlan(ERPNextTestSuite): rate = get_plan_rate(plan.name, start_date="2026-01-01", end_date="2026-03-31") self.assertEqual(rate, 300) - def test_monthly_rate_across_year_boundary_underbills(self): - # SUSPECTED BUG: no_of_months uses relativedelta(end, start).months, which drops - # the years component, so a 14-month span (Jan 2026 to Feb 2027) that should bill - # 1400 (14 x 100) is billed as only 200 (2 months). Locking the current (wrong) - # value so a fix trips this test; the correct expectation is 1400. + def test_monthly_rate_across_year_boundary(self): + # a 14-month span (Jan 2026 to Feb 2027) bills all 14 months, not just the + # 2-month remainder that relativedelta.months alone would give plan = self.make_plan(price_determination="Monthly Rate", cost=100) plan.insert() rate = get_plan_rate(plan.name, start_date="2026-01-01", end_date="2027-02-28") - self.assertEqual(rate, 200) + self.assertEqual(rate, 1400)