test(opportunity): cover the mark-as-lost flow

declare_enquiry_lost had almost no coverage. Add tests that marking an
Opportunity as lost records the lost reasons, competitors and detailed
reason and sets status to Lost, and that it is blocked when an active
(submitted) Quotation exists.
This commit is contained in:
Nabin Hait
2026-06-22 12:33:19 +05:30
parent c4bbf22c62
commit 61c2e7ad6e

View File

@@ -100,6 +100,42 @@ class TestOpportunity(ERPNextTestSuite):
opp.opportunity_owner = None
self.assertIsNone(opp.get_notification_email())
def test_declare_enquiry_lost(self):
lost_reason = _ensure_master("Opportunity Lost Reason", "lost_reason", "_Test Lost - Too Expensive")
competitor = _ensure_master("Competitor", "competitor_name", "_Test Competitor")
opp = make_opportunity(with_items=0)
opp.declare_enquiry_lost(
lost_reasons_list=[{"lost_reason": lost_reason}],
competitors=[{"competitor": competitor}],
detailed_reason="Budget too high",
)
opp.reload()
self.assertEqual(opp.status, "Lost")
self.assertEqual(opp.order_lost_reason, "Budget too high")
self.assertEqual([d.lost_reason for d in opp.lost_reasons], [lost_reason])
self.assertEqual([d.competitor for d in opp.competitors], [competitor])
def test_declare_lost_blocked_when_quotation_active(self):
opp = make_opportunity(with_items=0)
quotation = make_quotation(opp.name)
quotation.append("items", {"item_code": "_Test Item", "qty": 1})
quotation.run_method("set_missing_values")
quotation.run_method("calculate_taxes_and_totals")
quotation.submit()
# A submitted, still-active quotation exists, so the opportunity can't be marked lost
opp.reload()
self.assertRaises(frappe.ValidationError, opp.declare_enquiry_lost, [], [], "x")
self.assertNotEqual(opp.status, "Lost")
def _ensure_master(doctype, fieldname, value):
if not frappe.db.exists(doctype, value):
frappe.get_doc({"doctype": doctype, fieldname: value}).insert(ignore_permissions=True)
return value
def make_opportunity_from_lead(company):
new_lead_email_id = f"new{random_string(5)}@example.com"