Skip to content

Commit 42e1862

Browse files
committed
Allow sending data from linked objects to geoserver
1 parent 0a96af3 commit 42e1862

1 file changed

Lines changed: 85 additions & 21 deletions

File tree

src/server/sendDataToGeoserver.js

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,20 @@ async function updateObject(object, objectType, uuid, currentObject, configurati
9595
if (!wfsConfiguration) return;
9696

9797
for (let fieldConfiguration of wfsConfiguration.geometry_fields) {
98-
const geometryIds = getGeometryIds(object, fieldConfiguration.field_path.split('.'));
98+
const geometryIds = await getGeometryIds(object, fieldConfiguration.field_path.split('.'));
9999
if (geometryIds.length && await hasUsedGeometryIds(configuration, geometryIds, uuid)) {
100100
return throwErrorToFrontend('Eine oder mehrere Geometrien sind bereits mit anderen Objekten verknüpft.', undefined, 'multipleGeometryLinking');
101101
}
102102

103-
await editGeometries(object, fieldConfiguration, geometryIds, authorizationString);
103+
await editGeometries(object, currentObject, fieldConfiguration, geometryIds, authorizationString);
104104
await deleteGeometries(fieldConfiguration, geometryIds, currentObject, authorizationString);
105105
}
106106
}
107107

108-
function getGeometryIds(object, pathSegments) {
108+
async function getGeometryIds(object, pathSegments) {
109109
let geometryIds = [];
110110

111-
for (let fieldValue of getFieldValues(object, pathSegments)) {
111+
for (let fieldValue of await getFieldValues(object, pathSegments)) {
112112
if (!fieldValue?.geometry_ids?.length) continue;
113113
geometryIds = geometryIds.concat(
114114
fieldValue.geometry_ids.filter(value => value !== undefined)
@@ -161,9 +161,10 @@ function getGeometryFieldPaths(configuration) {
161161
return fieldPaths;
162162
}
163163

164-
async function editGeometries(object, fieldConfiguration, geometryIds, authorizationString) {
164+
async function editGeometries(object, currentObject, fieldConfiguration, geometryIds, authorizationString) {
165165
if (isSendingDataToGeoserverActivated(fieldConfiguration, geometryIds)) {
166-
const changeMap = getChangeMap(object, fieldConfiguration);
166+
addDataFromCurrentObject(object, currentObject);
167+
const changeMap = await getChangeMap(object, fieldConfiguration);
167168
if (Object.keys(changeMap).length) {
168169
await performEditTransaction(geometryIds, changeMap, fieldConfiguration, authorizationString);
169170
}
@@ -172,12 +173,12 @@ async function editGeometries(object, fieldConfiguration, geometryIds, authoriza
172173

173174
async function deleteGeometries(fieldConfiguration, geometryIds, currentObject, authorizationString) {
174175
if (!currentObject) return;
175-
const deletedGeometryIds = getDeletedGeometryIds(geometryIds, currentObject, fieldConfiguration);
176+
const deletedGeometryIds = await getDeletedGeometryIds(geometryIds, currentObject, fieldConfiguration);
176177
if (deletedGeometryIds.length) await performDeleteTransaction(deletedGeometryIds, fieldConfiguration, authorizationString);
177178
}
178179

179-
function getDeletedGeometryIds(geometryIds, currentObject, fieldConfiguration) {
180-
const currentGeometryIds = getGeometryIds(currentObject, fieldConfiguration.field_path.split('.'));
180+
async function getDeletedGeometryIds(geometryIds, currentObject, fieldConfiguration) {
181+
const currentGeometryIds = await getGeometryIds(currentObject, fieldConfiguration.field_path.split('.'));
181182
return currentGeometryIds.filter(geometryId => !geometryIds.includes(geometryId));
182183
}
183184

@@ -187,39 +188,102 @@ function isSendingDataToGeoserverActivated(fieldConfiguration, geometryIds) {
187188
&& geometryIds?.length;
188189
}
189190

190-
function getChangeMap(object, fieldConfiguration) {
191+
function addDataFromCurrentObject(object, currentObject) {
192+
for (let fieldName of Object.keys(object)) {
193+
if (!fieldName.startsWith('_reverse_nested')) continue;
194+
if (Array.isArray(object[fieldName])) {
195+
for (let i = 0; i < object[fieldName].length; i++) {
196+
if (!hasLinkedObjectData(object[fieldName][i])) {
197+
object[fieldName][i] = currentObject[fieldName].find(entry => entry._id = object[fieldName][i]._id);
198+
}
199+
}
200+
} else if (!hasLinkedObjectData(object[fieldName])) {
201+
object[fieldName] = currentObject[fieldName];
202+
}
203+
}
204+
}
205+
206+
function hasLinkedObjectData(fieldContent) {
207+
return Object.values(fieldContent).find(subfield => subfield._mask && subfield._objecttype);
208+
}
209+
210+
211+
async function getChangeMap(object, fieldConfiguration) {
191212
const changeMap = {};
213+
const linkedObjects = {};
192214
addPoolFieldToChangeMap(object, fieldConfiguration, changeMap);
193215

194-
const fields = fieldConfiguration.fields ?? [];
195-
return fields.reduce((result, field) => {
216+
if (!fieldConfiguration.fields) return changeMap;
217+
218+
for (let field of fieldConfiguration.fields) {
196219
const wfsFieldName = field.wfs_field_name;
197220
const fylrFieldName = field.fylr_field_name;
198221
const fylrFunction = field.fylr_function;
199222
if (fylrFieldName || fylrFunction) {
200223
const fieldValue = fylrFieldName
201-
? getFieldValues(object, fylrFieldName.split('.'))?.[0]
224+
? (await getFieldValues(object, fylrFieldName.split('.'), linkedObjects))?.[0]
202225
: getValueFromCustomFunction(object, fylrFunction);
203-
addToChangeMap(wfsFieldName, fieldValue, result);
226+
addToChangeMap(wfsFieldName, fieldValue, changeMap);
204227
}
205-
return result;
206-
}, changeMap);
228+
}
229+
230+
return changeMap;
207231
}
208232

209-
function getFieldValues(object, pathSegments) {
233+
async function getFieldValues(object, pathSegments, linkedObjects = {}) {
210234
const fieldName = pathSegments.shift();
211-
const field = object[fieldName];
235+
let field = object[fieldName];
212236

213237
if (field === undefined) {
214238
return [];
215239
} else if (pathSegments.length === 0) {
216240
return [field];
217241
} else if (Array.isArray(field)) {
218-
return field.map(entry => getFieldValues(entry, pathSegments.slice()))
219-
.filter(data => data !== undefined)
242+
let fieldValues = [];
243+
for (let entry of field) {
244+
fieldValues.push(await getFieldValues(entry, pathSegments.slice()));
245+
}
246+
return fieldValues.filter(data => data !== undefined)
220247
.reduce((result, fieldValues) => result.concat(fieldValues), []);
221248
} else {
222-
return getFieldValues(field, pathSegments);
249+
if (field._objecttype && field._mask && field[field._objecttype]?._id) {
250+
field = await getLinkedObject(field, linkedObjects);
251+
}
252+
return await getFieldValues(field, pathSegments);
253+
}
254+
}
255+
256+
async function getLinkedObject(field, linkedObjects) {
257+
const cachedObject = linkedObjects[field._objecttype]?.[field._id];
258+
if (cachedObject) return cachedObject;
259+
260+
const linkedObject = (await fetchObject(field._objecttype, field._mask, field[field._objecttype]._id))?.[field._objecttype];
261+
if (!linkedObject) {
262+
throwErrorToFrontend('Das Objekt ' + field[field._objecttype]._id + ' vom Typ ' + field._objecttype + ' konnte nicht abgerufen werden.');
263+
}
264+
265+
addToLinkedObjectsCache(linkedObject, linkedObjects);
266+
267+
return linkedObject;
268+
}
269+
270+
function addToLinkedObjectsCache(linkedObject, linkedObjects) {
271+
const objectType = linkedObject._objecttype;
272+
const id = linkedObject._id;
273+
274+
if (!linkedObjects[objectType]) linkedObject[objectType] = {};
275+
linkedObject[objectType][id] = linkedObject;
276+
}
277+
278+
async function fetchObject(objectType, mask, id) {
279+
const url = info.api_url + '/api/v1/db/' + objectType + '/' + mask + '/' + id + '?access_token=' + info.api_user_access_token;
280+
281+
try {
282+
const response = await fetch(url, { method: 'GET' });
283+
const result = await response.json();
284+
return result?.length ? result[0] : undefined;
285+
} catch (err) {
286+
throwErrorToFrontend('Objektabfrage fehlgeschlagen.', JSON.stringify(err));
223287
}
224288
}
225289

0 commit comments

Comments
 (0)