fix(controllers): fix supplier-RFQ portal list query (wrong column + Postgres DISTINCT)

rfq_transaction_list had two defects introduced when it was converted to the query
builder:

1. `party.supplier == party[0]` compared supplier to a column literally named "0"
   (a stray index on the DocType, not the intended `parties[0]` value). This renders
   as `supplier = \`0\`` / `supplier = "0"` and errors on BOTH engines
   (MariaDB: Unknown column '0'; Postgres: column "0" does not exist), so the
   supplier portal RFQ list was completely broken.
2. SELECT DISTINCT ordered by `creation`, which is not in the select list. Postgres
   rejects this ("for SELECT DISTINCT, ORDER BY expressions must appear in select list").

Compare against `parties[0]` and add `creation` to the select list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit a7d9078bf4)

# Conflicts:
#	erpnext/controllers/tests/test_website_list_for_contact.py
This commit is contained in:
Mihir Kandoi
2026-06-21 10:14:42 +05:30
committed by Mergify
parent 1a348d8e6e
commit 3abadc7a5f
2 changed files with 39 additions and 2 deletions

View File

@@ -0,0 +1,36 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import json
from erpnext.tests.utils import ERPNextTestSuite
class TestWebsiteListForContact(ERPNextTestSuite):
def test_get_list_context_currency_symbols(self):
# get_list_context builds the enabled-currency symbol map via frappe.get_all (converted from
# raw SQL). Exercises that query and asserts a known enabled currency is present.
from erpnext.controllers.website_list_for_contact import get_list_context
context = get_list_context()
symbols = json.loads(context["currency_symbols"])
self.assertIsInstance(symbols, dict)
self.assertIn("USD", symbols)
def test_rfq_transaction_list_returns_supplier_rfq(self):
# rfq_transaction_list filters RFQs by the supplier (parties[0]) and uses SELECT DISTINCT with
# ORDER BY creation -- both must be valid on Postgres, and the supplier filter must compare to the
# party value (not a stray `party[0]` column reference).
from erpnext.buying.doctype.request_for_quotation.test_request_for_quotation import (
make_request_for_quotation,
)
from erpnext.controllers.website_list_for_contact import rfq_transaction_list
rfq = make_request_for_quotation()
supplier = rfq.suppliers[0].supplier
rows = rfq_transaction_list(
"Request for Quotation Supplier", "Request for Quotation", [supplier], 0, 20
)
self.assertIn(rfq.name, [row.name for row in rows])

View File

@@ -181,9 +181,10 @@ def rfq_transaction_list(parties_doctype, doctype, parties, limit_start, limit_p
party = frappe.qb.DocType(parties_doctype)
data = (
frappe.qb.from_(party)
.select(party.parent.as_("name"), party.supplier)
# creation must be selected: Postgres requires SELECT DISTINCT order-by exprs in the select list
.select(party.parent.as_("name"), party.supplier, party.creation)
.distinct()
.where((party.supplier == party[0]) & (party.docstatus == 1))
.where((party.supplier == parties[0]) & (party.docstatus == 1))
.orderby(party.creation, order=frappe.qb.desc)
.limit(limit_page_length)
.offset(limit_start)