diff --git a/server/routes/utils/dataReportHelpers.ts b/server/routes/utils/dataReportHelpers.ts index a7bee2b9..1316eff7 100644 --- a/server/routes/utils/dataReportHelpers.ts +++ b/server/routes/utils/dataReportHelpers.ts @@ -126,20 +126,55 @@ export const getOpenSearchData = ( // get all the fields of type date and format them to excel format for (let dateField of report._source.dateFields) { const dateValue = data._source[dateField]; - if (dateValue && dateValue.length !== 0) { - if (dateValue instanceof Array) { - // loop through array - dateValue.forEach((element, index) => { - data._source[dateField][index] = moment( - fields[dateField][index] - ).format(dateFormat); - }); + const fieldDateValue = fields[dateField]; + const isDateFieldPresent = isKeyPresent(data._source, dateField); + + if (isDateFieldPresent) { + // if its not a nested date field + if (keys.length === 1) { + // if conditions to determine if the date field's value is an array or a string + if (typeof dateValue === 'string') { + data._source[keys] = moment(dateValue).format(dateFormat); + } else if ( + fieldDateValue.length !== 0 && + fieldDateValue instanceof Array + ) { + fieldDateValue.forEach((element, index) => { + data._source[keys][index] = moment(element).format(dateFormat); + }); + } else { + data._source[keys] = []; + } + // else to cover cases with nested date fields } else { - // The fields response always returns an array of values for each field - // https://www.elastic.co/guide/en/elasticsearch/reference/master/search-fields.html#search-fields-response - data._source[dateField] = moment(fields[dateField][0]).format( - dateFormat - ); + let keyElement = keys.shift(); + // if conditions to determine if the date field's value is an array or a string + if (typeof fieldDateValue === 'string') { + keys.push(moment(fieldDateValue).format(dateFormat)); + } else if ( + fieldDateValue.length !== 0 && + fieldDateValue instanceof Array + ) { + let tempArray: string[] = []; + fieldDateValue.forEach((index) => { + tempArray.push(moment(index).format(dateFormat)); + }); + keys.push(tempArray); + } else { + keys.push([]); + } + const nestedJSON = arrayToNestedJSON(keys); + let keyLength = Object.keys(data._source); + // to check if the nested field have anyother keys apart from date field + if (tempKeyElement.includes(keyElement) || keyLength.length > 1) { + data._source[keyElement] = { + ...data._source[keyElement], + ...nestedJSON, + }; + } else { + data._source[keyElement] = nestedJSON; + tempKeyElement.push(keyElement); + } } } } @@ -226,6 +261,32 @@ function sanitize(doc: any) { return doc; } +function arrayToNestedJSON(arr: string[]) { + if (arr.length === 0) { + return null; + } else if (arr.length === 1) { + return arr[0]; + } else { + const key = arr[0]; + const rest = arr.slice(1); + return { [key]: arrayToNestedJSON(rest) }; + } +} + +function isKeyPresent(data: any, key: string): boolean { + if (typeof data === 'object' && data !== null) { + if (key in data) { + return true; + } + for (const value of Object.values(data)) { + if (isKeyPresent(value, key)) { + return true; + } + } + } + return false; +} + const addDocValueFields = (report: any, requestBody: any) => { const docValues = []; for (const dateType of report._source.dateFields) {