mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-13 17:20:36 +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):
|
if not frappe.db.exists("DocType", self.filters.doc_type):
|
||||||
frappe.throw(_("Invalid Document Type {0}").format(self.filters.doc_type))
|
frappe.throw(_("Invalid Document Type {0}").format(self.filters.doc_type))
|
||||||
|
|
||||||
order_types = frappe.get_all(
|
# frappe drops ORDER BY for distinct queries on postgres (db_query), so a SQL order_by="order_type"
|
||||||
self.filters.doc_type,
|
# would be a no-op there and the leaf rows would come back unordered. Sort in python with casefold
|
||||||
filters={"order_type": ["is", "set"]},
|
# to keep the report's order-type row order deterministic, case-insensitive (matching MariaDB's
|
||||||
pluck="order_type",
|
# collation), and identical on both engines.
|
||||||
distinct=True,
|
order_types = sorted(
|
||||||
order_by="order_type",
|
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="")]
|
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["Sales"]["total"], expected, places=2)
|
||||||
self.assertAlmostEqual(rows["Order Types"]["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):
|
def test_customer_group_by_quantity(self):
|
||||||
"""value_quantity='Quantity' switches the selected value column (total_qty)."""
|
"""value_quantity='Quantity' switches the selected value column (total_qty)."""
|
||||||
_columns, data, *_ = execute(
|
_columns, data, *_ = execute(
|
||||||
|
|||||||
Reference in New Issue
Block a user