From f27b754570b006c415bc3675ad64772ee112426d Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Fri, 19 Sep 2025 16:23:26 +0530 Subject: [PATCH 1/3] fix(subscription): include days before (cherry picked from commit 9164162a9e80e685bb596d4f9eb87573125d8ede) --- .../doctype/subscription/subscription.py | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index 8c4d21ac3fb..77aacb4ac60 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -490,11 +490,18 @@ class Subscription(Document): if prorate is None: prorate = False + prorate_factor = 1 if prorate: prorate_factor = get_prorata_factor( self.current_invoice_end, self.current_invoice_start, - cint(self.generate_invoice_at == "Beginning of the current subscription period"), + cint( + self.generate_invoice_at + in [ + "Beginning of the current subscription period", + "Days before the current subscription period", + ] + ), ) items = [] @@ -511,33 +518,19 @@ class Subscription(Document): deferred = frappe.db.get_value("Item", item_code, deferred_field) - if not prorate: - item = { - "item_code": item_code, - "qty": plan.qty, - "rate": get_plan_rate( - plan.plan, - plan.qty, - party, - self.current_invoice_start, - self.current_invoice_end, - ), - "cost_center": plan_doc.cost_center, - } - else: - item = { - "item_code": item_code, - "qty": plan.qty, - "rate": get_plan_rate( - plan.plan, - plan.qty, - party, - self.current_invoice_start, - self.current_invoice_end, - prorate_factor, - ), - "cost_center": plan_doc.cost_center, - } + item = { + "item_code": item_code, + "qty": plan.qty, + "rate": get_plan_rate( + plan.plan, + plan.qty, + party, + self.current_invoice_start, + self.current_invoice_end, + prorate_factor, + ), + "cost_center": plan_doc.cost_center, + } if deferred: item.update( From 3fcbb10155eb7c7ebfd766389d67abc74ff3b4f8 Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Fri, 19 Sep 2025 16:48:35 +0530 Subject: [PATCH 2/3] refactor(subscription): default prorate 0 (cherry picked from commit eda1dae882f0bc39790a84850175f90e83439916) --- erpnext/accounts/doctype/subscription/subscription.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index 77aacb4ac60..623073c7e45 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -483,12 +483,10 @@ class Subscription(Document): return invoice - def get_items_from_plans(self, plans: list[dict[str, str]], prorate: bool | None = None) -> list[dict]: + def get_items_from_plans(self, plans: list[dict[str, str]], prorate: int = 0) -> list[dict]: """ Returns the `Item`s linked to `Subscription Plan` """ - if prorate is None: - prorate = False prorate_factor = 1 if prorate: From 4f067085e73caca988d6625e7f74b245aff7cfac Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Mon, 6 Oct 2025 12:12:27 +0530 Subject: [PATCH 3/3] test: add invoice generation before period with prorate (cherry picked from commit b452e06b82756d91e062f1906e0eb8408a4abd03) --- .../doctype/subscription/test_subscription.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py index b1e5653e8da..1d906fb9276 100644 --- a/erpnext/accounts/doctype/subscription/test_subscription.py +++ b/erpnext/accounts/doctype/subscription/test_subscription.py @@ -8,6 +8,7 @@ from frappe.utils.data import ( add_days, add_months, add_to_date, + add_years, cint, date_diff, flt, @@ -555,6 +556,33 @@ class TestSubscription(FrappeTestCase): subscription.reload() self.assertEqual(len(subscription.invoices), 0) + def test_invoice_generation_days_before_subscription_period_with_prorate(self): + settings = frappe.get_single("Subscription Settings") + settings.prorate = 1 + settings.save() + + create_plan( + plan_name="_Test Plan Name 5", + cost=1000, + billing_interval="Year", + billing_interval_count=1, + currency="INR", + ) + + start_date = add_days(nowdate(), 2) + + subscription = create_subscription( + start_date=start_date, + party_type="Supplier", + party="_Test Supplier", + generate_invoice_at="Days before the current subscription period", + generate_new_invoices_past_due_date=1, + number_of_days=2, + plans=[{"plan": "_Test Plan Name 5", "qty": 1}], + ) + subscription.process(nowdate()) + self.assertEqual(len(subscription.invoices), 1) + def make_plans(): create_plan(plan_name="_Test Plan Name", cost=900, currency="INR")