From f95baa54dec0e4be164279b370017f348c57ef91 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 2 Jul 2026 15:42:07 +0530 Subject: [PATCH 1/2] test: Territory-wise Sales report coverage --- .../test_territory_wise_sales.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py diff --git a/erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py b/erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py new file mode 100644 index 00000000000..f2b81bfb633 --- /dev/null +++ b/erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py @@ -0,0 +1,59 @@ +# Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +import frappe + +from erpnext.selling.doctype.quotation.test_quotation import make_quotation +from erpnext.selling.report.territory_wise_sales.territory_wise_sales import execute +from erpnext.tests.utils import ERPNextTestSuite + +TERRITORY = "_Test Territory" + + +class TestTerritoryWiseSales(ERPNextTestSuite): + """The report walks the Opportunity -> Quotation -> Sales Order -> Sales Invoice + funnel and totals each stage's amount per territory.""" + + def make_opportunity(self, amount=5000): + return frappe.get_doc( + { + "doctype": "Opportunity", + "opportunity_from": "Customer", + "party_name": "_Test Customer", + "territory": TERRITORY, + "company": "_Test Company", + "currency": "INR", + "opportunity_amount": amount, + "transaction_date": "2026-06-01", + } + ).insert() + + def make_quotation_for(self, opportunity, qty, rate): + qo = make_quotation(item="_Test Item", qty=qty, rate=rate, do_not_save=True) + qo.opportunity = opportunity.name + qo.insert() + qo.submit() + return qo + + def amount_for(self, territory, field): + for row in execute(frappe._dict({"company": "_Test Company"}))[1]: + if row["territory"] == territory: + return row[field] + return 0 + + def test_opportunity_amount_grouped_by_territory(self): + before = self.amount_for(TERRITORY, "opportunity_amount") + opp = self.make_opportunity(5000) + self.assertEqual(opp.territory, TERRITORY) + + after = self.amount_for(TERRITORY, "opportunity_amount") + self.assertEqual(after - before, 5000) + + def test_quotation_amount_flows_from_opportunity(self): + before = self.amount_for(TERRITORY, "quotation_amount") + + opp = self.make_opportunity() + quotation = self.make_quotation_for(opp, qty=2, rate=500) + + after = self.amount_for(TERRITORY, "quotation_amount") + self.assertEqual(after - before, quotation.base_grand_total) From 087fb29d51f8e8a3bdced4a3b3287b28fc866720 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 2 Jul 2026 17:13:42 +0530 Subject: [PATCH 2/2] test: narrow Territory-wise Sales docstring to covered stages --- .../report/territory_wise_sales/test_territory_wise_sales.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py b/erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py index f2b81bfb633..8a069810b8d 100644 --- a/erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py +++ b/erpnext/selling/report/territory_wise_sales/test_territory_wise_sales.py @@ -12,7 +12,10 @@ TERRITORY = "_Test Territory" class TestTerritoryWiseSales(ERPNextTestSuite): """The report walks the Opportunity -> Quotation -> Sales Order -> Sales Invoice - funnel and totals each stage's amount per territory.""" + funnel and totals each stage's amount per territory. + + These tests cover the Opportunity and Quotation stages; the Sales Order and + Sales Invoice (order_amount / billing_amount) stages are not yet exercised.""" def make_opportunity(self, amount=5000): return frappe.get_doc(