mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-16 16:08:39 +00:00
Merge pull request #56251 from mihir-kandoi/pg-ci-remaining-failures
fix(postgres): resolve remaining Postgres test failures on develop
This commit is contained in:
@@ -479,7 +479,7 @@ def reconcile(doc: None | str = None) -> None:
|
||||
finally:
|
||||
if reconciled_entries == total_allocations:
|
||||
frappe.db.set_value("Process Payment Reconciliation Log", log, "status", "Reconciled")
|
||||
frappe.db.set_value("Process Payment Reconciliation Log", log, "reconciled", True)
|
||||
frappe.db.set_value("Process Payment Reconciliation Log", log, "reconciled", 1)
|
||||
frappe.db.set_value("Process Payment Reconciliation", doc, "status", "Completed")
|
||||
else:
|
||||
if frappe.db.get_value("Process Payment Reconciliation", doc, "status") != "Paused":
|
||||
|
||||
@@ -424,7 +424,7 @@ class TestUnreconcilePayment(ERPNextTestSuite, AccountsTestMixin):
|
||||
self.disable_advance_as_liability()
|
||||
|
||||
def test_07_adv_from_so_to_invoice(self):
|
||||
frappe.db.set_value("Company", self.company, "book_advance_payments_in_separate_party_account", True)
|
||||
frappe.db.set_value("Company", self.company, "book_advance_payments_in_separate_party_account", 1)
|
||||
frappe.db.set_value(
|
||||
"Company", self.company, "default_advance_received_account", "Advance Received - _TC"
|
||||
)
|
||||
|
||||
@@ -1402,16 +1402,18 @@ def validate_bom_no(item, bom_no):
|
||||
|
||||
|
||||
def _bom_contains_item(bom, item):
|
||||
item = item.lower()
|
||||
item_lower = item.lower()
|
||||
for d in bom.items:
|
||||
if d.item_code.lower() == item:
|
||||
if d.item_code.lower() == item_lower:
|
||||
return True
|
||||
for d in bom.secondary_items:
|
||||
if d.item_code.lower() == item:
|
||||
if d.item_code.lower() == item_lower:
|
||||
return True
|
||||
|
||||
# Use the original-cased `item` for the Item lookup: names are case-sensitive on Postgres,
|
||||
# so a lowercased name would miss the record and drop the variant->template BOM match.
|
||||
return (
|
||||
bom.item.lower() == item
|
||||
bom.item.lower() == item_lower
|
||||
or bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower()
|
||||
)
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ class TestBin(ERPNextTestSuite):
|
||||
bin1.insert()
|
||||
|
||||
bin2 = frappe.get_doc(doctype="Bin", item_code=item_code, warehouse=warehouse)
|
||||
frappe.db.savepoint("dup_bin")
|
||||
with self.assertRaises(frappe.UniqueValidationError):
|
||||
bin2.insert()
|
||||
frappe.db.rollback(save_point="dup_bin") # preserve transaction in postgres
|
||||
|
||||
# util method should handle it
|
||||
bin = _create_bin(item_code, warehouse)
|
||||
|
||||
@@ -751,7 +751,9 @@ class TestItem(ERPNextTestSuite):
|
||||
item_doc = frappe.get_doc("Item", item_code)
|
||||
new_barcode = item_doc.append("barcodes")
|
||||
new_barcode.update(barcode_properties_list[0])
|
||||
frappe.db.savepoint("dup_barcode")
|
||||
self.assertRaises(frappe.UniqueValidationError, item_doc.save)
|
||||
frappe.db.rollback(save_point="dup_barcode") # preserve transaction in postgres
|
||||
|
||||
# Add invalid barcode - should cause InvalidBarcode
|
||||
item_doc = frappe.get_doc("Item", item_code)
|
||||
@@ -768,10 +770,14 @@ class TestItem(ERPNextTestSuite):
|
||||
|
||||
now = time.time()
|
||||
one_year_ago = now - 366 * 24 * 60 * 60
|
||||
# posting_date is a calendar date; its midnight unix timestamp (taken in the database
|
||||
# session timezone) can sit up to a day ahead of the precise current instant when the app
|
||||
# timezone is ahead of UTC, so allow a day of slack on the upper bound.
|
||||
one_day = 24 * 60 * 60
|
||||
|
||||
for timestamp, count in data.items():
|
||||
self.assertIsInstance(timestamp, int)
|
||||
self.assertTrue(one_year_ago <= timestamp <= now)
|
||||
self.assertTrue(one_year_ago <= timestamp <= now + one_day)
|
||||
self.assertIsInstance(count, int)
|
||||
self.assertGreaterEqual(count, 0)
|
||||
|
||||
|
||||
@@ -9,6 +9,37 @@ INDEXED_FIELDS = {
|
||||
}
|
||||
|
||||
|
||||
def _is_leading_index_column(doctype: str, field: str) -> bool:
|
||||
"""Whether `field` is the first column of some index on the doctype's table.
|
||||
|
||||
`SHOW INDEX` is MySQL-only; on Postgres read the leading key column (indkey[0])
|
||||
from the pg_index catalog. Both check the same thing across engines.
|
||||
"""
|
||||
table = f"tab{doctype}"
|
||||
if frappe.db.db_type == "postgres":
|
||||
return bool(
|
||||
frappe.db.sql(
|
||||
"""
|
||||
SELECT 1
|
||||
FROM pg_index i
|
||||
JOIN pg_class t ON t.oid = i.indrelid
|
||||
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = i.indkey[0]
|
||||
WHERE t.relname = %s AND a.attname = %s
|
||||
LIMIT 1
|
||||
""",
|
||||
(table, field),
|
||||
)
|
||||
)
|
||||
# `table` is a trusted constant (from INDEXED_FIELDS); a table identifier can't be a %s
|
||||
# placeholder in SHOW INDEX, so the f-string is unavoidable and safe here.
|
||||
return bool(
|
||||
frappe.db.sql(
|
||||
f"""SHOW INDEX FROM `{table}` WHERE Column_name = %s AND Seq_in_index = 1""",
|
||||
(field,),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class TestPerformance(ERPNextTestSuite):
|
||||
def test_ensure_indexes(self):
|
||||
# These fields are not explicitly indexed BUT they are prefix in some
|
||||
@@ -17,8 +48,6 @@ class TestPerformance(ERPNextTestSuite):
|
||||
for doctype, fields in INDEXED_FIELDS.items():
|
||||
for field in fields:
|
||||
self.assertTrue(
|
||||
frappe.db.sql(
|
||||
f"""SHOW INDEX FROM `tab{doctype}`
|
||||
WHERE Column_name = "{field}" AND Seq_in_index = 1"""
|
||||
)
|
||||
_is_leading_index_column(doctype, field),
|
||||
msg=f"{field} is not the leading column of any index on tab{doctype}",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user