diff --git a/lib/data/json.js b/lib/data/json.js index ef53c6bc4..81c1f70f8 100644 --- a/lib/data/json.js +++ b/lib/data/json.js @@ -206,14 +206,15 @@ const submissionToOData = (fields, table, submission, options = {}) => new Promi if (fieldPtr != null) { if (getBranchState(fieldStack, table) === 1) { const dataPtr = ptr(dataStack); + const { name, type } = fieldPtr; // we have a value and a place to put it. preprocess it if necessary and write. - if ((fieldPtr.type === 'structure') || (fieldPtr.type === 'repeat')) { + if ((type === 'structure') || (type === 'repeat')) { // do nothing. - } else if (fieldPtr.type === 'int') { - dataPtr[fieldPtr.name] = parseInt(text, 10); - } else if (fieldPtr.type === 'decimal') { - dataPtr[fieldPtr.name] = parseFloat(text); - } else if (fieldPtr.type === 'geopoint') { + } else if (type === 'int') { + dataPtr[name] = parseInt(text, 10); + } else if (type === 'decimal') { + dataPtr[name] = parseFloat(text); + } else if (type === 'geopoint') { // all formats require this parsing/formulation: const [ lat, lon, altitude ] = text.split(/\s+/g).map(parseFloat); if ((lat == null) || (lon == null)) return; @@ -222,13 +223,18 @@ const submissionToOData = (fields, table, submission, options = {}) => new Promi if ((altitude != null) && !Number.isNaN(altitude)) coordinates.push(altitude); if (options.wkt === true) // well-known text format: - dataPtr[fieldPtr.name] = `POINT (${coordinates.join(' ')})`; + dataPtr[name] = `POINT (${coordinates.join(' ')})`; else // geojson is the default: - dataPtr[fieldPtr.name] = { type: 'Point', coordinates }; + dataPtr[name] = { type: 'Point', coordinates }; + } else if (type === 'dateTime') { + // patch a case where jr/collect outputs eg +07 as the tz, but most + // specs require +07:00 + const trimmed = text.trim(); + dataPtr[name] = /[+-]\d\d$/.test(trimmed) ? trimmed + ':00' : trimmed; } else { // we have to account for multiple text events for the same field, // since for whatever reason entities decode into their own text events. - dataPtr[fieldPtr.name] = (dataPtr[fieldPtr.name] || '') + text; + dataPtr[name] = (dataPtr[name] || '') + text; } } } diff --git a/test/unit/data/json.js b/test/unit/data/json.js index ac05a94be..ff6afdaf0 100644 --- a/test/unit/data/json.js +++ b/test/unit/data/json.js @@ -50,6 +50,9 @@ describe('submissionToOData', () => { decimal: { name: 'decimal', type: 'decimal' }, geopoint: { name: 'geopoint', type: 'geopoint' }, geopointNoAlt: { name: 'geopointNoAlt', type: 'geopoint' }, + dateTime: { name: 'dateTime', type: 'dateTime' }, + dateTimeWhitespace: { name: 'dateTimeWhitespace', type: 'dateTime' }, + dateTimeCorrect: { name: 'dateTimeCorrect', type: 'dateTime' }, text: { name: 'text', type: 'text' }, other: { name: 'other', type: 'other' } }; @@ -58,6 +61,11 @@ describe('submissionToOData', () => { 3.14 4.8 15.16 23.42 11.38 -11.38 + 2019-01-01T00:00:00.000-08 + + 2019-01-01T00:00:00.000-08 + + 2019-01-01T00:00:00.000-08:00 hello what could it be? `); @@ -69,6 +77,9 @@ describe('submissionToOData', () => { decimal: 3.14, geopoint: { type: 'Point', coordinates: [ 15.16, 4.8, 23.42 ] }, geopointNoAlt: { type: 'Point', coordinates: [ -11.38, 11.38 ] }, + dateTime: '2019-01-01T00:00:00.000-08:00', + dateTimeWhitespace: '2019-01-01T00:00:00.000-08:00', + dateTimeCorrect: '2019-01-01T00:00:00.000-08:00', text: 'hello', other: 'what could it be?' }]);