@@ -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
173174async 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