mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-12 06:01:46 +00:00
Merge pull request #56329 from mihir-kandoi/pg-sales-analytics-order
fix(selling): deterministic Sales Analytics order-type row order on both engines
This commit is contained in:
@@ -528,12 +528,18 @@ class Analytics:
|
||||
if not frappe.db.exists("DocType", self.filters.doc_type):
|
||||
frappe.throw(_("Invalid Document Type {0}").format(self.filters.doc_type))
|
||||
|
||||
order_types = frappe.get_all(
|
||||
self.filters.doc_type,
|
||||
filters={"order_type": ["is", "set"]},
|
||||
pluck="order_type",
|
||||
distinct=True,
|
||||
order_by="order_type",
|
||||
# frappe drops ORDER BY for distinct queries on postgres (db_query), so a SQL order_by="order_type"
|
||||
# would be a no-op there and the leaf rows would come back unordered. Sort in python with casefold
|
||||
# to keep the report's order-type row order deterministic, case-insensitive (matching MariaDB's
|
||||
# collation), and identical on both engines.
|
||||
order_types = sorted(
|
||||
frappe.get_all(
|
||||
self.filters.doc_type,
|
||||
filters={"order_type": ["is", "set"]},
|
||||
pluck="order_type",
|
||||
distinct=True,
|
||||
),
|
||||
key=str.casefold,
|
||||
)
|
||||
|
||||
self.group_entries = [frappe._dict(name="Order Types", lft=0, rgt=2, parent="")]
|
||||
|
||||
@@ -117,6 +117,30 @@ class TestSalesAnalytics(ERPNextTestSuite):
|
||||
self.assertAlmostEqual(rows["Sales"]["total"], expected, places=2)
|
||||
self.assertAlmostEqual(rows["Order Types"]["total"], expected, places=2)
|
||||
|
||||
def test_order_type_leaf_rows_in_sorted_order(self):
|
||||
"""get_teams fetches distinct order_types; frappe drops the SQL ORDER BY for distinct queries on
|
||||
postgres, so the report sorts the order-type rows in python (key=str.casefold) to keep them in a
|
||||
deterministic, case-insensitive order identical on both engines."""
|
||||
for order_type in ("Shopping Cart", "Maintenance", "Sales"): # created out of sorted order
|
||||
so = make_sales_order(
|
||||
company=COMPANY,
|
||||
customer=CUSTOMER,
|
||||
qty=1,
|
||||
rate=100,
|
||||
transaction_date="2019-04-12",
|
||||
do_not_submit=True,
|
||||
)
|
||||
so.order_type = order_type
|
||||
so.submit()
|
||||
|
||||
columns, data, *_ = execute(self._base_filters(tree_type="Order Type"))
|
||||
|
||||
mine = {"Sales", "Maintenance", "Shopping Cart"}
|
||||
leaves = [row["entity"] for row in data if row.get("entity") in mine]
|
||||
# the order-type rows must appear in casefold-sorted order on both engines
|
||||
self.assertEqual(leaves, sorted(leaves, key=str.casefold))
|
||||
self.assertEqual(set(leaves), mine)
|
||||
|
||||
def test_customer_group_by_quantity(self):
|
||||
"""value_quantity='Quantity' switches the selected value column (total_qty)."""
|
||||
_columns, data, *_ = execute(
|
||||
|
||||
Reference in New Issue
Block a user