diff --git a/src/pages/GFMIS/TransactionDataGrid.js b/src/pages/GFMIS/TransactionDataGrid.js index 1f346ab..eeb8659 100644 --- a/src/pages/GFMIS/TransactionDataGrid.js +++ b/src/pages/GFMIS/TransactionDataGrid.js @@ -75,8 +75,22 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a headerName: 'Transaction Date', flex: 1, minWidth: 150, - valueGetter: (params) => { - return DateUtils.dateStr(params?.value); + // sorting/filtering uses this value + valueGetter: (params) => DateUtils.toDate(params?.value), + + // display uses this (params.value is the *Date* returned above) + valueFormatter: (params) => { + const d = params.value; // Date or Invalid Date + return d instanceof Date && !isNaN(d.getTime()) + ? DateUtils.dateStr(d) + : ""; + }, + + // make sorting 100% deterministic + sortComparator: (v1, v2) => { + const t1 = v1 instanceof Date && !isNaN(v1.getTime()) ? v1.getTime() : -Infinity; + const t2 = v2 instanceof Date && !isNaN(v2.getTime()) ? v2.getTime() : -Infinity; + return t1 - t2; } }, { diff --git a/src/pages/Payment/Search_GLD/DataGrid.js b/src/pages/Payment/Search_GLD/DataGrid.js index 5537d31..d24fed0 100644 --- a/src/pages/Payment/Search_GLD/DataGrid.js +++ b/src/pages/Payment/Search_GLD/DataGrid.js @@ -110,8 +110,23 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a headerName: 'Transaction Date', flex: 1, minWidth: 150, - valueGetter: (params) => { - return DateUtils.dateStr(params?.value); + + // sorting/filtering uses this value + valueGetter: (params) => DateUtils.toDate(params?.value), + + // display uses this (params.value is the *Date* returned above) + valueFormatter: (params) => { + const d = params.value; // Date or Invalid Date + return d instanceof Date && !isNaN(d.getTime()) + ? DateUtils.dateStr(d) + : ""; + }, + + // make sorting 100% deterministic + sortComparator: (v1, v2) => { + const t1 = v1 instanceof Date && !isNaN(v1.getTime()) ? v1.getTime() : -Infinity; + const t2 = v2 instanceof Date && !isNaN(v2.getTime()) ? v2.getTime() : -Infinity; + return t1 - t2; } }, { diff --git a/src/pages/Proof/Search_GLD/DataGrid.js b/src/pages/Proof/Search_GLD/DataGrid.js index 08a6176..90af342 100644 --- a/src/pages/Proof/Search_GLD/DataGrid.js +++ b/src/pages/Proof/Search_GLD/DataGrid.js @@ -60,8 +60,22 @@ export default function SearchPublicNoticeTable({searchCriteria, applyGridOnRead headerName: 'Proof Issue Date', flex: 1, minWidth: 200, - valueGetter: (params) => { - return DateUtils.datetimeStr(params?.value); + // sorting/filtering uses this value + valueGetter: (params) => DateUtils.toDate(params?.value), + + // display uses this (params.value is the *Date* returned above) + valueFormatter: (params) => { + const d = params.value; // Date or Invalid Date + return d instanceof Date && !isNaN(d.getTime()) + ? DateUtils.dateStr(d) + : ""; + }, + + // make sorting 100% deterministic + sortComparator: (v1, v2) => { + const t1 = v1 instanceof Date && !isNaN(v1.getTime()) ? v1.getTime() : -Infinity; + const t2 = v2 instanceof Date && !isNaN(v2.getTime()) ? v2.getTime() : -Infinity; + return t1 - t2; } }, { @@ -70,62 +84,23 @@ export default function SearchPublicNoticeTable({searchCriteria, applyGridOnRead headerName: 'Confirmed/ Return Date', flex: 1, minWidth: 200, - type: 'dateTime', - - valueGetter: (params) => { - const v = params?.value; - if (v == null) return null; - - // 1) Number => epoch timestamp (ms or seconds) - if (typeof v === "number") { - if (!Number.isFinite(v)) return null; - - // Heuristic: if it's too small, it's probably seconds - // (ms in 2026 is ~1.7e12, seconds is ~1.7e9) - const ms = v < 1e11 ? v * 1000 : v; - - const d = new Date(ms); - return Number.isNaN(d.getTime()) ? null : d; - } - - // 2) Array => [Y, M, D, h, m, s] - if (Array.isArray(v)) { - if (v.length < 3) return null; - - const year = Number(v[0]); - const month = Number(v[1]); // expecting 1-12 - const day = Number(v[2]); - const hour = Number(v[3] ?? 0); - const minute = Number(v[4] ?? 0); - const second = Number(v[5] ?? 0); - - if (![year, month, day, hour, minute, second].every(Number.isFinite)) return null; - if (month < 1 || month > 12) return null; - - const d = new Date(year, month - 1, day, hour, minute, second); - - // Guard against JS "auto-fixing" invalid dates (e.g., Feb 31 -> Mar 2) - if ( - d.getFullYear() !== year || - d.getMonth() !== month - 1 || - d.getDate() !== day - ) return null; - - return d; - } - - // 3) Optional: ISO string support (if it ever appears) - if (typeof v === "string") { - const d = new Date(v); - return Number.isNaN(d.getTime()) ? null : d; - } - - return null; - }, + // sorting/filtering uses this value + valueGetter: (params) => DateUtils.toDate(params?.value), + // display uses this (params.value is the *Date* returned above) valueFormatter: (params) => { - return params.value ? DateUtils.datetimeStr(params.value) : ""; + const d = params.value; // Date or Invalid Date + return d instanceof Date && !isNaN(d.getTime()) + ? DateUtils.dateStr(d) + : ""; }, + + // make sorting 100% deterministic + sortComparator: (v1, v2) => { + const t1 = v1 instanceof Date && !isNaN(v1.getTime()) ? v1.getTime() : -Infinity; + const t2 = v2 instanceof Date && !isNaN(v2.getTime()) ? v2.getTime() : -Infinity; + return t1 - t2; + } }, { id: 'contactPerson', diff --git a/src/utils/DateUtils.js b/src/utils/DateUtils.js index c2a4df1..5877593 100644 --- a/src/utils/DateUtils.js +++ b/src/utils/DateUtils.js @@ -93,6 +93,29 @@ export const convertToDate = (date)=>{ return date; } +export const toDate = (date) => { + if (date === null || date === undefined || date === '') return new Date(NaN); + + if (typeof date === 'number') { + // support seconds or millis + const ms = date < 1e12 ? date * 1000 : date; + return new Date(ms); + } + + if (Array.isArray(date)) { + const [y, m, d, hh = 0, mm = 0, ss = 0] = date; + return new Date(y, m - 1, d, hh, mm, ss); + } + + if (typeof date === 'string') { + const normalized = date.includes(' ') && !date.includes('T') ? date.replace(' ', 'T') : date; + const d = new Date(normalized); + return isNaN(d.getTime()) ? new Date(NaN) : d; + } + + return date instanceof Date ? date : new Date(NaN); +}; + export const formatDateForLocale = (date, intl, locale) => { const fmt = intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }); let s = dateFormat(date, fmt) || "";