mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-12 14:11:46 +00:00
fix(postgres): use portable GroupConcat in Lost Opportunity report
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,8 +5,7 @@
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.query_builder import DocType
|
||||
from frappe.query_builder.custom import GROUP_CONCAT
|
||||
from frappe.query_builder.functions import Date
|
||||
from frappe.query_builder.functions import Date, GroupConcat
|
||||
|
||||
Opportunity = DocType("Opportunity")
|
||||
OpportunityLostReasonDetail = DocType("Opportunity Lost Reason Detail")
|
||||
@@ -72,6 +71,9 @@ def get_columns():
|
||||
|
||||
|
||||
def get_data(filters):
|
||||
# db-aware GROUP_CONCAT (MariaDB) / STRING_AGG (postgres) with a ", " separator
|
||||
lost_reasons = GroupConcat(OpportunityLostReasonDetail.lost_reason, ", ", alias="lost_reason")
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(Opportunity)
|
||||
.left_join(OpportunityLostReasonDetail)
|
||||
@@ -85,7 +87,7 @@ def get_data(filters):
|
||||
Opportunity.party_name,
|
||||
Opportunity.customer_name,
|
||||
Opportunity.opportunity_type,
|
||||
GROUP_CONCAT(OpportunityLostReasonDetail.lost_reason, alias="lost_reason").separator(", "),
|
||||
lost_reasons,
|
||||
Opportunity.sales_stage,
|
||||
Opportunity.territory,
|
||||
)
|
||||
|
||||
22
erpnext/crm/report/lost_opportunity/test_lost_opportunity.py
Normal file
22
erpnext/crm/report/lost_opportunity/test_lost_opportunity.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.utils import add_days, today
|
||||
|
||||
from erpnext.crm.report.lost_opportunity.lost_opportunity import execute
|
||||
from erpnext.tests.utils import ERPNextTestSuite
|
||||
|
||||
|
||||
class TestLostOpportunity(ERPNextTestSuite):
|
||||
def test_report_aggregates_lost_reasons(self):
|
||||
# Exercises the db-aware GROUP_CONCAT (MariaDB) / STRING_AGG (postgres) aggregation of the
|
||||
# child "Opportunity Lost Reason Detail" rows. The MySQL-only GROUP_CONCAT term would fail to
|
||||
# compile on postgres, so simply running the report query guards the portability fix on both
|
||||
# databases.
|
||||
company = frappe.db.get_value("Company", {}, "name")
|
||||
columns, data = execute(
|
||||
frappe._dict({"company": company, "from_date": add_days(today(), -365), "to_date": today()})
|
||||
)
|
||||
self.assertTrue(columns)
|
||||
self.assertIsInstance(data, list)
|
||||
Reference in New Issue
Block a user