diff --git a/alfa-client/apps/admin/src/app/app.component.spec.ts b/alfa-client/apps/admin/src/app/app.component.spec.ts
index baa8c7fcc532a0e859fe596782a94bf7b2257803..cc45121d96c5ad9236bb5a834c42ab4714617175 100644
--- a/alfa-client/apps/admin/src/app/app.component.spec.ts
+++ b/alfa-client/apps/admin/src/app/app.component.spec.ts
@@ -297,7 +297,7 @@ describe('AppComponent', () => {
       it('should navigate to statistik if aggregation mapping link exists', () => {
         component._navigateByConfiguration(createConfigurationResource([ConfigurationLinkRel.AGGREGATION_MAPPINGS]));
 
-        expect(router.navigate).toHaveBeenCalledWith(['/statistik']);
+        expect(router.navigate).toHaveBeenCalledWith(['/aggregation-mapping']);
       });
 
       it('should navigate to unavailable page if no link exists', () => {
diff --git a/alfa-client/apps/admin/src/app/app.component.ts b/alfa-client/apps/admin/src/app/app.component.ts
index 909b6cd198bd3ccb91dd61e922abb6a1ed79210c..989a4ad4b3fd75d2767750eb535a8db27a9d6c29 100644
--- a/alfa-client/apps/admin/src/app/app.component.ts
+++ b/alfa-client/apps/admin/src/app/app.component.ts
@@ -123,7 +123,7 @@ export class AppComponent implements OnInit {
     if (hasLink(configurationResource, ConfigurationLinkRel.SETTING)) {
       this.navigate(ROUTES.POSTFACH);
     } else if (hasLink(configurationResource, ConfigurationLinkRel.AGGREGATION_MAPPINGS)) {
-      this.navigate(ROUTES.STATISTIK);
+      this.navigate(ROUTES.AGGREGATION_MAPPING);
     } else {
       this.navigate(ROUTES.UNAVAILABLE);
     }
diff --git a/alfa-client/apps/admin/src/app/app.routes.ts b/alfa-client/apps/admin/src/app/app.routes.ts
index c5974993c237ec15254220a64157b63ae0f46136..2d21b25201efc7da0c177426aea5f1ccc0feabbf 100644
--- a/alfa-client/apps/admin/src/app/app.routes.ts
+++ b/alfa-client/apps/admin/src/app/app.routes.ts
@@ -83,7 +83,7 @@ export const appRoutes: Route[] = [
     title: 'Unavailable',
   },
   {
-    path: ROUTES.STATISTIK,
+    path: ROUTES.AGGREGATION_MAPPING,
     component: StatistikPageComponent,
     title: 'Admin | Statistik',
     runGuardsAndResolvers: 'always',
@@ -91,7 +91,15 @@ export const appRoutes: Route[] = [
     data: <GuardData>{ linkRelName: ConfigurationLinkRel.AGGREGATION_MAPPINGS },
   },
   {
-    path: ROUTES.STATISTIK_NEU,
+    path: ROUTES.AGGREGATION_MAPPING_NEU,
+    component: StatistikFieldsFormPageComponent,
+    title: 'Admin | Statistik weitere Felder auswerten',
+    runGuardsAndResolvers: 'always',
+    canActivate: [configurationGuard],
+    data: <GuardData>{ linkRelName: ConfigurationLinkRel.AGGREGATION_MAPPINGS },
+  },
+  {
+    path: ROUTES.AGGREGATION_MAPPING_ID,
     component: StatistikFieldsFormPageComponent,
     title: 'Admin | Statistik weitere Felder auswerten',
     runGuardsAndResolvers: 'always',
diff --git a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html
index 0c1102a4c22c1603d4cc93f6baaaf5fcb2f94d40..c319836e14be9bee1d1314df5f293f09173a12b0 100644
--- a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html
+++ b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.html
@@ -4,7 +4,7 @@
   </ods-nav-item>
 }
 @if (configurationStateResource.resource | hasLink: configurationLinkRel.AGGREGATION_MAPPINGS) {
-  <ods-nav-item data-test-id="statistik-navigation" caption="Statistik" path="/statistik">
+  <ods-nav-item data-test-id="statistik-navigation" caption="Statistik" [path]="'/' + ROUTES.AGGREGATION_MAPPING">
     <ods-statistic-icon icon />
   </ods-nav-item>
 }
diff --git a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.ts b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.ts
index 0c9cddefff0b13b58d8dd915f44352b78bd60f2b..c0845f3f13cf83a993f7cbe48f8021d42a2097e2 100644
--- a/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.ts
+++ b/alfa-client/libs/admin/configuration/src/lib/menu-container/menu/menu.component.ts
@@ -1,4 +1,5 @@
 import { ConfigurationLinkRel, ConfigurationResource } from '@admin-client/configuration-shared';
+import { ROUTES } from '@admin-client/shared';
 import { HasLinkPipe, StateResource } from '@alfa-client/tech-shared';
 import { CommonModule } from '@angular/common';
 import { Component, Input } from '@angular/core';
@@ -14,4 +15,5 @@ export class MenuComponent {
   @Input() configurationStateResource: StateResource<ConfigurationResource>;
 
   public readonly configurationLinkRel = ConfigurationLinkRel;
+  public readonly ROUTES = ROUTES;
 }
diff --git a/alfa-client/libs/admin/reporting-shared/src/index.ts b/alfa-client/libs/admin/reporting-shared/src/index.ts
index 44ab78233d97deaf497e327e28f71c431ae6960e..42e6a9bbe06db6b16da1b80d8f8b7f902c421988 100644
--- a/alfa-client/libs/admin/reporting-shared/src/index.ts
+++ b/alfa-client/libs/admin/reporting-shared/src/index.ts
@@ -1,3 +1,4 @@
+export * from './lib/aggregation-mapping-list-resource.service';
 export * from './lib/aggregation-mapping-resource.service';
 export * from './lib/aggregation-mapping.model';
 export * from './lib/aggregation-mapping.provider';
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-list-resource.service.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-list-resource.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1378b74475c88940614acdf93cd68218ee9927ea
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-list-resource.service.ts
@@ -0,0 +1,26 @@
+import { ConfigurationLinkRel, ConfigurationResource, ConfigurationService } from '@admin-client/configuration-shared';
+import { ListResourceServiceConfig, ResourceListService, ResourceRepository } from '@alfa-client/tech-shared';
+import { AggregationMappingListLinkRel } from './aggregation-mapping.linkrel';
+import { AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model';
+
+export class AggregationMappingListResourceService extends ResourceListService<
+  ConfigurationResource,
+  AggregationMappingListResource,
+  AggregationMappingResource
+> {}
+
+export function createAggregationMappingListResourceService(
+  repository: ResourceRepository,
+  configurationService: ConfigurationService,
+) {
+  return new ResourceListService(buildConfig(configurationService), repository);
+}
+
+function buildConfig(configurationService: ConfigurationService): ListResourceServiceConfig<ConfigurationResource> {
+  return {
+    baseResource: configurationService.get(),
+    listLinkRel: ConfigurationLinkRel.AGGREGATION_MAPPINGS,
+    listResourceListLinkRel: AggregationMappingListLinkRel.LIST,
+    createLinkRel: AggregationMappingListLinkRel.SELF,
+  };
+}
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.spec.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0b2f68fab6d7716bb3e658cf8b848eac3ea1ed50
--- /dev/null
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.spec.ts
@@ -0,0 +1,213 @@
+import { AggregationMappingResource } from '@admin-client/reporting-shared';
+import { ROUTES } from '@admin-client/shared';
+import { NavigationService, RouteData } from '@alfa-client/navigation-shared';
+import {
+  createEmptyStateResource,
+  createStateResource,
+  decodeUrlFromEmbedding,
+  ResourceRepository,
+  ResourceServiceConfig,
+  StateResource,
+} from '@alfa-client/tech-shared';
+import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
+import { UrlSegment } from '@angular/router';
+import { faker } from '@faker-js/faker';
+import { afterAll, expect } from '@jest/globals';
+import { ResourceUri } from '@ngxp/rest';
+import { Observable, of } from 'rxjs';
+import { createRouteData, createUrlSegment } from '../../../../navigation-shared/test/navigation-test-factory';
+import { singleColdCompleted } from '../../../../tech-shared/test/marbles';
+import { createAggregationMappingResource } from '../../test/aggregation-mapping';
+import * as module from './aggregation-mapping-resource.service';
+
+jest.mock('@alfa-client/tech-shared', () => ({
+  ...jest.requireActual('@alfa-client/tech-shared'),
+  decodeUrlFromEmbedding: jest.fn(),
+}));
+
+const decodeUrlFromEmbeddingMock: jest.Mock = decodeUrlFromEmbedding as jest.Mock;
+
+describe('AggregationMappingResourceService', () => {
+  let repository: Mock<ResourceRepository>;
+  let navigationService: Mock<NavigationService>;
+
+  beforeEach(() => {
+    repository = mock(ResourceRepository);
+    navigationService = mock(NavigationService);
+  });
+
+  describe('build config', () => {
+    const _getResourceByNavigationRoute: jest.SpyInstance = jest
+      .spyOn(module, '_getResourceByNavigationRoute')
+      .mockImplementation();
+
+    afterAll(() => {
+      _getResourceByNavigationRoute.mockRestore();
+    });
+
+    it('should get resource by navigation route', () => {
+      module._buildResourceServiceConfig(useFromMock(repository), useFromMock(navigationService));
+
+      expect(_getResourceByNavigationRoute).toHaveBeenCalled();
+    });
+
+    it('should have aggregation mapping static resource', () => {
+      const staticResource: StateResource<AggregationMappingResource> = createStateResource(createAggregationMappingResource());
+      _getResourceByNavigationRoute.mockReturnValue(of(staticResource));
+
+      const config: ResourceServiceConfig<AggregationMappingResource> = module._buildResourceServiceConfig(
+        useFromMock(repository),
+        useFromMock(navigationService),
+      );
+
+      expect(config.resource).toBeObservable(singleColdCompleted(staticResource));
+    });
+  });
+
+  describe('get resource by navigation route', () => {
+    const routeData: RouteData = createRouteData();
+    const _isAggregationMappingEditUrl: jest.SpyInstance = jest
+      .spyOn(module, '_isAggregationMappingEditUrl')
+      .mockImplementation();
+    const _getAggregationMappingResourceByRoute: jest.SpyInstance = jest
+      .spyOn(module, '_getAggregationMappingResourceByRoute')
+      .mockImplementation();
+
+    beforeEach(() => {
+      navigationService.getCurrentRouteData.mockReturnValue(of(routeData));
+    });
+
+    afterAll(() => {
+      _isAggregationMappingEditUrl.mockRestore();
+      _getAggregationMappingResourceByRoute.mockRestore();
+    });
+
+    it('should get current route data', () => {
+      module._getResourceByNavigationRoute(useFromMock(repository), useFromMock(navigationService)).subscribe();
+
+      expect(navigationService.getCurrentRouteData).toHaveBeenCalled();
+    });
+
+    it('should check if url contains resource uri', () => {
+      module._getResourceByNavigationRoute(useFromMock(repository), useFromMock(navigationService)).subscribe();
+
+      expect(_isAggregationMappingEditUrl).toHaveBeenCalled();
+    });
+
+    it('should get aggregation mapping resource by route', () => {
+      module._getResourceByNavigationRoute(useFromMock(repository), useFromMock(navigationService)).subscribe();
+
+      expect(_getAggregationMappingResourceByRoute).toHaveBeenCalled();
+    });
+
+    it('should return aggregation mapping by route', () => {
+      const stateResource: StateResource<AggregationMappingResource> = createStateResource(createAggregationMappingResource());
+      _getAggregationMappingResourceByRoute.mockReturnValue(of(stateResource));
+      _isAggregationMappingEditUrl.mockReturnValue(true);
+
+      const resourceByRoute$: Observable<StateResource<AggregationMappingResource>> = module._getResourceByNavigationRoute(
+        useFromMock(repository),
+        useFromMock(navigationService),
+      );
+
+      expect(resourceByRoute$).toBeObservable(singleColdCompleted(stateResource));
+    });
+
+    it('should return empty state resource', () => {
+      const stateResource: StateResource<AggregationMappingResource> = createEmptyStateResource();
+      _isAggregationMappingEditUrl.mockReturnValue(false);
+
+      const resourceByRoute$: Observable<StateResource<AggregationMappingResource>> = module._getResourceByNavigationRoute(
+        useFromMock(repository),
+        useFromMock(navigationService),
+      );
+
+      expect(resourceByRoute$).toBeObservable(singleColdCompleted(stateResource));
+    });
+  });
+
+  describe('is aggregation mapping edit url', () => {
+    it.each([0, 1, 3])('should return false of wrong number of segments = %d', (numberOfSegments: number) => {
+      const routeData: RouteData = {
+        ...createRouteData(),
+        urlSegments: Array(numberOfSegments).fill(createUrlSegment()),
+      };
+
+      expect(module._isAggregationMappingEditUrl(routeData)).toBe(false);
+    });
+
+    it('should return false if first path is wrong', () => {
+      const routeData: RouteData = {
+        ...createRouteData(),
+        urlSegments: Array(2).fill(createUrlSegment()),
+      };
+
+      expect(module._isAggregationMappingEditUrl(routeData)).toBe(false);
+    });
+
+    it('should return false if second path is wrong', () => {
+      const firstUrlSegment: UrlSegment = createUrlSegment();
+      firstUrlSegment.path = ROUTES.AGGREGATION_MAPPING;
+      const secondUrlSegment: UrlSegment = createUrlSegment();
+      secondUrlSegment.path = 'neu';
+      const routeData: RouteData = {
+        ...createRouteData(),
+        urlSegments: [firstUrlSegment, secondUrlSegment],
+      };
+
+      expect(module._isAggregationMappingEditUrl(routeData)).toBe(false);
+    });
+
+    it('should return true', () => {
+      const firstUrlSegment: UrlSegment = createUrlSegment();
+      firstUrlSegment.path = ROUTES.AGGREGATION_MAPPING;
+      const secondUrlSegment: UrlSegment = createUrlSegment();
+      secondUrlSegment.path = faker.internet.url();
+      const routeData: RouteData = {
+        ...createRouteData(),
+        urlSegments: [firstUrlSegment, secondUrlSegment],
+      };
+
+      expect(module._isAggregationMappingEditUrl(routeData)).toBe(true);
+    });
+  });
+
+  describe('get aggregation mapping resource by route', () => {
+    const firstUrlSegment: UrlSegment = createUrlSegment();
+    firstUrlSegment.path = ROUTES.AGGREGATION_MAPPING;
+    const secondUrlSegment: UrlSegment = createUrlSegment();
+    secondUrlSegment.path = faker.internet.url();
+    const routeData: RouteData = {
+      ...createRouteData(),
+      urlSegments: [firstUrlSegment, secondUrlSegment],
+    };
+    const uri: ResourceUri = faker.internet.url();
+    const resource: AggregationMappingResource = createAggregationMappingResource();
+
+    beforeEach(() => {
+      decodeUrlFromEmbeddingMock.mockReturnValue(uri);
+      repository.getResource.mockReturnValue(of(resource));
+    });
+
+    it('should decode url', () => {
+      module._getAggregationMappingResourceByRoute(useFromMock(repository), routeData);
+
+      expect(decodeUrlFromEmbeddingMock).toHaveBeenCalledWith(secondUrlSegment.path);
+    });
+
+    it('should get resource', () => {
+      module._getAggregationMappingResourceByRoute(useFromMock(repository), routeData);
+
+      expect(repository.getResource).toHaveBeenCalledWith(uri);
+    });
+
+    it('should return state resource', () => {
+      const stateResource$: Observable<StateResource<AggregationMappingResource>> = module._getAggregationMappingResourceByRoute(
+        useFromMock(repository),
+        routeData,
+      );
+
+      expect(stateResource$).toBeObservable(singleColdCompleted(createStateResource(resource)));
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts
index 65eb7a8e1680b97f12cdba2556ae8d9d9041883c..e4937c3eb736c6460a9cd23daaabe5464adb18af 100644
--- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts
@@ -1,26 +1,71 @@
-import { ConfigurationLinkRel, ConfigurationResource, ConfigurationService } from '@admin-client/configuration-shared';
-import { ListResourceServiceConfig, ResourceListService, ResourceRepository } from '@alfa-client/tech-shared';
-import { AggregationMappingListLinkRel } from './aggregation-mapping.linkrel';
-import { AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model';
+import { ROUTES } from '@admin-client/shared';
+import { NavigationService, RouteData } from '@alfa-client/navigation-shared';
+import {
+  ApiResourceService,
+  createEmptyStateResource,
+  createStateResource,
+  decodeUrlFromEmbedding,
+  ResourceRepository,
+  ResourceServiceConfig,
+  StateResource,
+} from '@alfa-client/tech-shared';
+import { UrlSegment } from '@angular/router';
+import { iif, map, Observable, of, switchMap } from 'rxjs';
+import * as module from './aggregation-mapping-resource.service';
+import { AggregationMappingLinkRel } from './aggregation-mapping.linkrel';
+import { AggregationMappingResource } from './aggregation-mapping.model';
 
-export class AggregationMappingListResourceService extends ResourceListService<
-  ConfigurationResource,
-  AggregationMappingListResource,
+export class AggregationMappingResourceService extends ApiResourceService<
+  AggregationMappingResource,
   AggregationMappingResource
 > {}
 
 export function createAggregationMappingResourceService(
   repository: ResourceRepository,
-  configurationService: ConfigurationService,
-) {
-  return new ResourceListService(buildConfig(configurationService), repository);
+  navigationService: NavigationService,
+): AggregationMappingResourceService {
+  return new AggregationMappingResourceService(_buildResourceServiceConfig(repository, navigationService), repository);
 }
 
-function buildConfig(configurationService: ConfigurationService): ListResourceServiceConfig<ConfigurationResource> {
+export function _buildResourceServiceConfig(
+  repository: ResourceRepository,
+  navigationService: NavigationService,
+): ResourceServiceConfig<AggregationMappingResource> {
+  module._getResourceByNavigationRoute(repository, navigationService);
   return {
-    baseResource: configurationService.get(),
-    listLinkRel: ConfigurationLinkRel.AGGREGATION_MAPPINGS,
-    listResourceListLinkRel: AggregationMappingListLinkRel.LIST,
-    createLinkRel: AggregationMappingListLinkRel.SELF,
+    resource: module._getResourceByNavigationRoute(repository, navigationService),
+    getLinkRel: AggregationMappingLinkRel.SELF,
+    edit: { linkRel: AggregationMappingLinkRel.SELF },
+    delete: { linkRel: AggregationMappingLinkRel.SELF },
   };
 }
+
+export function _getResourceByNavigationRoute(
+  repository: ResourceRepository,
+  navigationService: NavigationService,
+): Observable<StateResource<AggregationMappingResource>> {
+  return navigationService
+    .getCurrentRouteData()
+    .pipe(
+      switchMap((route: RouteData) =>
+        iif(
+          () => module._isAggregationMappingEditUrl(route),
+          module._getAggregationMappingResourceByRoute(repository, route),
+          of(createEmptyStateResource<AggregationMappingResource>()),
+        ),
+      ),
+    );
+}
+
+export function _isAggregationMappingEditUrl(route: RouteData): boolean {
+  const urlSegments: UrlSegment[] = route.urlSegments;
+  return urlSegments.length === 2 && urlSegments[0].path === ROUTES.AGGREGATION_MAPPING && urlSegments[1].path !== 'neu';
+}
+
+export function _getAggregationMappingResourceByRoute(
+  repository: ResourceRepository,
+  route: RouteData,
+): Observable<StateResource<AggregationMappingResource>> {
+  const uri: string = decodeUrlFromEmbedding(route.urlSegments[1].path);
+  return repository.getResource(uri).pipe(map((resource: AggregationMappingResource) => createStateResource(resource)));
+}
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.linkrel.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.linkrel.ts
index a4a02bfd7087b105a9d0d2dd816aa2b180a4db9c..6aea64156f045b33fd70c20aa2427aaebb4ece32 100644
--- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.linkrel.ts
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.linkrel.ts
@@ -2,3 +2,7 @@ export enum AggregationMappingListLinkRel {
   LIST = 'aggregationMappings',
   SELF = 'self',
 }
+
+export enum AggregationMappingLinkRel {
+  SELF = 'self',
+}
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.provider.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.provider.ts
index 888d7154e81dbfe53fb7476e4de8835463de6d25..76d294de177ea685a3e9cbd849e5a032f5423101 100644
--- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.provider.ts
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.provider.ts
@@ -1,8 +1,13 @@
+import { NavigationService } from '@alfa-client/navigation-shared';
 import { ResourceRepository } from '@alfa-client/tech-shared';
 import { Provider } from '@angular/core';
 import { ConfigurationService } from 'libs/admin/configuration-shared/src/lib/configuration.service';
 import {
   AggregationMappingListResourceService,
+  createAggregationMappingListResourceService,
+} from './aggregation-mapping-list-resource.service';
+import {
+  AggregationMappingResourceService,
   createAggregationMappingResourceService,
 } from './aggregation-mapping-resource.service';
 import { AggregationMappingService } from './aggregation-mapping.service';
@@ -10,8 +15,13 @@ import { AggregationMappingService } from './aggregation-mapping.service';
 export const AggregationMappingProvider: Provider[] = [
   {
     provide: AggregationMappingListResourceService,
-    useFactory: createAggregationMappingResourceService,
+    useFactory: createAggregationMappingListResourceService,
     deps: [ResourceRepository, ConfigurationService],
   },
+  {
+    provide: AggregationMappingResourceService,
+    useFactory: createAggregationMappingResourceService,
+    deps: [ResourceRepository, NavigationService],
+  },
   AggregationMappingService,
 ];
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts
index d00e6923b00a28a9022ac67bf1531555e852f713..0846feed2dc535c4cfa67dc22287013d45b967a0 100644
--- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.spec.ts
@@ -2,26 +2,33 @@ import { createStateResource, StateResource } from '@alfa-client/tech-shared';
 import { Mock, mock } from '@alfa-client/test-utils';
 import { TestBed } from '@angular/core/testing';
 import { expect } from '@jest/globals';
-import { singleCold } from 'libs/tech-shared/test/marbles';
-import { Observable } from 'rxjs';
+import { singleCold, singleColdCompleted } from 'libs/tech-shared/test/marbles';
+import { Observable, of } from 'rxjs';
 import {
   createAggregationMapping,
   createAggregationMappingListResource,
   createAggregationMappingResource,
 } from '../../test/aggregation-mapping';
-import { AggregationMappingListResourceService } from './aggregation-mapping-resource.service';
+import { AggregationMappingListResourceService } from './aggregation-mapping-list-resource.service';
+import { AggregationMappingResourceService } from './aggregation-mapping-resource.service';
 import { AggregationMapping, AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model';
 import { AggregationMappingService } from './aggregation-mapping.service';
 
 describe('AggregationMappingService', () => {
   let service: AggregationMappingService;
   let listResourceService: Mock<AggregationMappingListResourceService>;
+  let resourceService: Mock<AggregationMappingResourceService>;
 
   beforeEach(() => {
     listResourceService = mock(AggregationMappingListResourceService);
+    resourceService = mock(AggregationMappingResourceService);
 
     TestBed.configureTestingModule({
-      providers: [AggregationMappingService, { provide: AggregationMappingListResourceService, useValue: listResourceService }],
+      providers: [
+        AggregationMappingService,
+        { provide: AggregationMappingListResourceService, useValue: listResourceService },
+        { provide: AggregationMappingResourceService, useValue: resourceService },
+      ],
     });
 
     service = TestBed.inject(AggregationMappingService);
@@ -87,4 +94,39 @@ describe('AggregationMappingService', () => {
       expect(listResourceService.refresh).toHaveBeenCalled();
     });
   });
+
+  describe('get by current url', () => {
+    const stateResource = createStateResource(createAggregationMappingResource());
+    beforeEach(() => {
+      resourceService.get = jest.fn().mockReturnValue(of(stateResource));
+    });
+
+    it('should call resource service', () => {
+      service.getByCurrentUrl();
+
+      expect(resourceService.get).toHaveBeenCalled();
+    });
+
+    it('should emit resource', () => {
+      expect(service.getByCurrentUrl()).toBeObservable(singleColdCompleted(stateResource));
+    });
+  });
+
+  describe('save', () => {
+    const aggregationMapping: AggregationMapping = createAggregationMapping();
+    const stateResource = createStateResource(createAggregationMappingResource());
+    beforeEach(() => {
+      resourceService.save = jest.fn().mockReturnValue(of(stateResource));
+    });
+
+    it('should call resource service', () => {
+      service.save(aggregationMapping);
+
+      expect(resourceService.save).toHaveBeenCalledWith(aggregationMapping);
+    });
+
+    it('should emit saved state resource', () => {
+      expect(service.save(aggregationMapping)).toBeObservable(singleColdCompleted(stateResource));
+    });
+  });
 });
diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts
index 00402e238cce0455a7a0a25ced6fb70219216d24..19c85af76cad3ee04dd180d4bd7628271e9a3df5 100644
--- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts
+++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping.service.ts
@@ -1,12 +1,14 @@
 import { StateResource } from '@alfa-client/tech-shared';
 import { inject, Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
-import { AggregationMappingListResourceService } from './aggregation-mapping-resource.service';
+import { AggregationMappingListResourceService } from './aggregation-mapping-list-resource.service';
+import { AggregationMappingResourceService } from './aggregation-mapping-resource.service';
 import { AggregationMapping, AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model';
 
 @Injectable()
 export class AggregationMappingService {
-  readonly listService = inject(AggregationMappingListResourceService);
+  private readonly listService = inject(AggregationMappingListResourceService);
+  private readonly resourceService = inject(AggregationMappingResourceService);
 
   public getList(): Observable<StateResource<AggregationMappingListResource>> {
     return this.listService.getList();
@@ -19,4 +21,12 @@ export class AggregationMappingService {
   public refreshList(): void {
     this.listService.refresh();
   }
+
+  public getByCurrentUrl(): Observable<StateResource<AggregationMappingResource>> {
+    return this.resourceService.get();
+  }
+
+  public save(aggregationMapping: AggregationMapping): Observable<StateResource<AggregationMappingResource>> {
+    return this.resourceService.save(aggregationMapping);
+  }
 }
diff --git a/alfa-client/libs/admin/shared/src/lib/routes.ts b/alfa-client/libs/admin/shared/src/lib/routes.ts
index 090a9f3a7d82d6c3489bfa5c542b31592c177e06..cf1a2212026d934f4f29b358a7a21b01164c811f 100644
--- a/alfa-client/libs/admin/shared/src/lib/routes.ts
+++ b/alfa-client/libs/admin/shared/src/lib/routes.ts
@@ -28,6 +28,7 @@ export enum ROUTES {
   BENUTZER_ID = 'benutzer/:userid',
   ORGANISATIONSEINHEITEN = 'organisationseinheiten',
   UNAVAILABLE = 'unavailable',
-  STATISTIK = 'statistik',
-  STATISTIK_NEU = 'statistik/neu',
+  AGGREGATION_MAPPING = 'aggregation-mapping',
+  AGGREGATION_MAPPING_NEU = 'aggregation-mapping/neu',
+  AGGREGATION_MAPPING_ID = 'aggregation-mapping/:aggregationMappingId',
 }
diff --git a/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.html b/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.html
index 931f6462619cd1420536a4715b500759de8a70ac..777c081ff0800b3fab3fb01dfd073dd9d770e8d0 100644
--- a/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.html
+++ b/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.html
@@ -1,4 +1,4 @@
-<ods-list-item [path]="" [attr.data-test-id]="aggregationMapping.name | convertForDataTest">
+<ods-list-item [path]="aggregationMapping | toResourceUri" [attr.data-test-id]="aggregationMapping.name | convertForDataTest">
   <dl class="flex-1 font-semibold">
     <dt class="sr-only">Name</dt>
     <dd data-test-class="fullname">{{ aggregationMapping.name }}</dd>
diff --git a/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.spec.ts
index 7e48ac908db1d0c99b9357fd4744db48841268ff..18d620f575972e8fea06ee9982c0e06d43216f58 100644
--- a/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.spec.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.spec.ts
@@ -1,21 +1,42 @@
+import { AggregationMappingResource } from '@admin-client/reporting-shared';
+import { ToResourceUriPipe } from '@alfa-client/tech-shared';
+import { getElementFromFixtureByType } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { expect } from '@jest/globals';
+import { ListItemComponent } from '@ods/system';
+import { MockComponent } from 'ng-mocks';
+import { createAggregationMappingResource } from '../../../../../reporting-shared/test/aggregation-mapping';
 import { AggregationMappingListItemComponent } from './aggregation-mapping-list-item.component';
 
 describe('AggregationMappingListItemComponent', () => {
   let component: AggregationMappingListItemComponent;
   let fixture: ComponentFixture<AggregationMappingListItemComponent>;
 
+  const toResourceUriPipe: ToResourceUriPipe = new ToResourceUriPipe();
+  const aggregationMappingResource: AggregationMappingResource = createAggregationMappingResource();
+
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      imports: [AggregationMappingListItemComponent],
+      imports: [AggregationMappingListItemComponent, ToResourceUriPipe, MockComponent(ListItemComponent)],
     }).compileComponents();
 
     fixture = TestBed.createComponent(AggregationMappingListItemComponent);
     component = fixture.componentInstance;
+    component.aggregationMapping = aggregationMappingResource;
     fixture.detectChanges();
   });
 
   it('should create', () => {
     expect(component).toBeTruthy();
   });
+
+  describe('template', () => {
+    describe('list item', () => {
+      it('should have inputs', () => {
+        const comp: ListItemComponent = getElementFromFixtureByType(fixture, ListItemComponent);
+
+        expect(comp.path).toEqual(toResourceUriPipe.transform(aggregationMappingResource));
+      });
+    });
+  });
 });
diff --git a/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.ts b/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.ts
index c022babf739f7b4028ad13adbad87ff078e01082..6880096a779fa36e88b62dba199d952c7d34d9c7 100644
--- a/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/aggregation-mapping-list/aggregation-mapping-list-item/aggregation-mapping-list-item.component.ts
@@ -1,5 +1,5 @@
 import { AggregationMappingResource } from '@admin-client/reporting-shared';
-import { ConvertForDataTestPipe } from '@alfa-client/tech-shared';
+import { ConvertForDataTestPipe, ToResourceUriPipe } from '@alfa-client/tech-shared';
 import { Component, Input } from '@angular/core';
 import { ListItemComponent } from '@ods/system';
 
@@ -7,7 +7,7 @@ import { ListItemComponent } from '@ods/system';
   selector: 'admin-aggregation-mapping-list-item',
   standalone: true,
   templateUrl: './aggregation-mapping-list-item.component.html',
-  imports: [ConvertForDataTestPipe, ListItemComponent],
+  imports: [ConvertForDataTestPipe, ListItemComponent, ToResourceUriPipe],
   styles: [':host {@apply block}'],
 })
 export class AggregationMappingListItemComponent {
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html
index bd98c2aaea1352190b8720b6804999d16368a686..434802447a84d958df25655e23f35e255746effb 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-container/statistik-container.component.html
@@ -26,7 +26,7 @@
 <h1 class="heading-1" data-test-id="statistik-header-text">Statistik</h1>
 <ods-routing-button
   class="my-4 w-fit"
-  [linkPath]="ROUTES.STATISTIK_NEU"
+  [linkPath]="ROUTES.AGGREGATION_MAPPING_NEU"
   text="Weitere Felder auswerten"
   dataTestId="weitere-felder-auswerten-button"
 />
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html
index f81771fedaf501971ef73be12b7b34bad5ac7fa4..84f59729b87800db58a80cbd887a46bba3970278 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.html
@@ -1,43 +1,45 @@
 <h2 class="heading-2" data-test-id="statistik-fields-form-header-text">Felder zur Auswertung hinzufügen</h2>
 
-<div class="flex max-w-4xl flex-col gap-4">
-  <form class="form flex-col" [formGroup]="formService.form" class="flex flex-col gap-2">
-    <ods-text-editor
-      [formControlName]="StatistikFieldsFormService.FIELD_NAME"
-      label="Name *"
-      placeholder=""
-      data-test-id="statistik-name-text-editor"
-      dataTestId="statistik-name"
-    ></ods-text-editor>
-    <div [formGroupName]="StatistikFieldsFormService.FIELD_FORM_IDENTIFIER" class="flex flex-col gap-4">
+<ods-spinner [stateResource]="aggregationMappingStateResource$ | async">
+  <div class="flex max-w-4xl flex-col gap-4">
+    <form class="form flex-col" [formGroup]="formService.form" class="flex flex-col gap-2">
       <ods-text-editor
-        [formControlName]="StatistikFieldsFormService.FIELD_FORM_ENGINE_NAME"
-        label="Formengine *"
-        placeholder="Tragen Sie hier die Formengine des Formulars ein."
-        data-test-id="form-engine-name"
-        dataTestId="form-engine-name"
+        [formControlName]="StatistikFieldsFormService.FIELD_NAME"
+        label="Name *"
+        placeholder=""
+        data-test-id="statistik-name-text-editor"
+        dataTestId="statistik-name"
       ></ods-text-editor>
-      <ods-text-editor
-        [formControlName]="StatistikFieldsFormService.FIELD_FORM_ID"
-        label="FormID *"
-        placeholder="Tragen Sie hier die FormID des Formulars ein."
-        data-test-id="form-id"
-        dataTestId="form-id"
-      ></ods-text-editor>
-    </div>
-    <admin-statistik-fields-form-mapping />
-  </form>
-  <ods-button
-    text="Datenfeld hinzufügen"
-    dataTestId="add-mapping-button"
-    data-test-id="add-mapping"
-    (clickEmitter)="formService.addMapping()"
-  >
-    <ods-plus-icon icon class="fill-whitetext" />
-  </ods-button>
+      <div [formGroupName]="StatistikFieldsFormService.FIELD_FORM_IDENTIFIER" class="flex flex-col gap-4">
+        <ods-text-editor
+          [formControlName]="StatistikFieldsFormService.FIELD_FORM_ENGINE_NAME"
+          label="Formengine *"
+          placeholder="Tragen Sie hier die Formengine des Formulars ein."
+          data-test-id="form-engine-name"
+          dataTestId="form-engine-name"
+        ></ods-text-editor>
+        <ods-text-editor
+          [formControlName]="StatistikFieldsFormService.FIELD_FORM_ID"
+          label="FormID *"
+          placeholder="Tragen Sie hier die FormID des Formulars ein."
+          data-test-id="form-id"
+          dataTestId="form-id"
+        ></ods-text-editor>
+      </div>
+      <admin-statistik-fields-form-mapping />
+    </form>
+    <ods-button
+      text="Datenfeld hinzufügen"
+      dataTestId="add-mapping-button"
+      data-test-id="add-mapping"
+      (clickEmitter)="formService.addMapping()"
+    >
+      <ods-plus-icon icon class="fill-whitetext" />
+    </ods-button>
 
-  <div class="mt-4 flex gap-4">
-    <admin-save-button [successLinkPath]="Routes.STATISTIK" />
-    <admin-cancel-button [linkPath]="Routes.STATISTIK" />
+    <div class="mt-4 flex gap-4">
+      <admin-save-button [successLinkPath]="Routes.AGGREGATION_MAPPING" />
+      <admin-cancel-button [linkPath]="Routes.AGGREGATION_MAPPING" />
+    </div>
   </div>
-</div>
+</ods-spinner>
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.spec.ts
index fc823f9d6c91b1c46c8fd4a96ca5f3acf90854ee..5dc2a0eafa7308b02ec56dac0011b9866e507cf2 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.spec.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.spec.ts
@@ -1,12 +1,24 @@
-import { ADMIN_FORMSERVICE } from '@admin-client/shared';
-import { EMPTY_STRING } from '@alfa-client/tech-shared';
-import { dispatchEventFromFixture, existsAsHtmlElement, mock, Mock, MockEvent } from '@alfa-client/test-utils';
+import { AggregationMappingResource } from '@admin-client/reporting-shared';
+import { ADMIN_FORMSERVICE, ROUTES } from '@admin-client/shared';
+import { createStateResource, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
+import {
+  dispatchEventFromFixture,
+  existsAsHtmlElement,
+  getElementFromFixtureByType,
+  mock,
+  Mock,
+  MockEvent,
+} from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
+import { expect } from '@jest/globals';
 import { TextEditorComponent } from '@ods/component';
 import { ButtonComponent, PlusIconComponent } from '@ods/system';
 import { MockComponent } from 'ng-mocks';
+import { of } from 'rxjs';
 import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test';
+import { singleColdCompleted } from '../../../../../tech-shared/test/marbles';
+import { createAggregationMappingResource } from '../../../../reporting-shared/test/aggregation-mapping';
 import { AdminCancelButtonComponent } from '../../../../shared/src/lib/admin-cancel-button/admin-cancel-button.component';
 import { AdminSaveButtonComponent } from '../../../../shared/src/lib/admin-save-button/admin-save-button.component';
 import { StatistikFieldsFormComponent } from './statistik-fields-form.component';
@@ -21,6 +33,10 @@ describe('AdminStatistikFieldsFormComponent', () => {
   const formIdInputTestId: string = getDataTestIdOf('form-id');
   const addMappingButton: string = getDataTestIdOf('add-mapping');
 
+  const aggregationMappingStateResource: StateResource<AggregationMappingResource> = createStateResource(
+    createAggregationMappingResource(),
+  );
+
   const formBuilder: FormBuilder = new FormBuilder();
 
   let formService: Mock<StatistikFieldsFormService>;
@@ -35,6 +51,7 @@ describe('AdminStatistikFieldsFormComponent', () => {
     });
 
     formService = <any>{ ...mock(StatistikFieldsFormService), form };
+    formService.get = jest.fn().mockReturnValue(of(aggregationMappingStateResource));
 
     await TestBed.configureTestingModule({
       imports: [
@@ -73,6 +90,16 @@ describe('AdminStatistikFieldsFormComponent', () => {
     expect(component).toBeTruthy();
   });
 
+  describe('component', () => {
+    it('should get aggregation mapping from form service', () => {
+      expect(formService.get).toHaveBeenCalled();
+    });
+
+    it('should initial values', () => {
+      expect(component.aggregationMappingStateResource$).toBeObservable(singleColdCompleted(aggregationMappingStateResource));
+    });
+  });
+
   describe('template', () => {
     describe('form engine input', () => {
       it('should exists', () => {
@@ -109,5 +136,21 @@ describe('AdminStatistikFieldsFormComponent', () => {
         });
       });
     });
+
+    describe('save button', () => {
+      it('should have link path', () => {
+        const comp: AdminSaveButtonComponent = getElementFromFixtureByType(fixture, AdminSaveButtonComponent);
+
+        expect(comp.successLinkPath).toEqual(ROUTES.AGGREGATION_MAPPING);
+      });
+    });
+
+    describe('cancel button', () => {
+      it('should have link path', () => {
+        const comp: AdminCancelButtonComponent = getElementFromFixtureByType(fixture, AdminCancelButtonComponent);
+
+        expect(comp.linkPath).toEqual(ROUTES.AGGREGATION_MAPPING);
+      });
+    });
   });
 });
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.ts
index bd10b259535147a21ed8f6a1913e2365a23a7c1b..9709c01258eddc3fe1cbd5d40854511868e759b4 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields-form.component.ts
@@ -1,8 +1,12 @@
+import { AggregationMappingResource } from '@admin-client/reporting-shared';
 import { ADMIN_FORMSERVICE, AdminCancelButtonComponent, AdminSaveButtonComponent, ROUTES } from '@admin-client/shared';
+import { StateResource } from '@alfa-client/tech-shared';
+import { AsyncPipe } from '@angular/common';
 import { Component, inject } from '@angular/core';
 import { ReactiveFormsModule } from '@angular/forms';
-import { TextEditorComponent } from '@ods/component';
+import { SpinnerComponent, TextEditorComponent } from '@ods/component';
 import { ButtonComponent, PlusIconComponent } from '@ods/system';
+import { Observable } from 'rxjs';
 import { StatistikFieldsMappingsFormComponent } from './statistik-fields-mappings-form/statistik-fields-mappings-form.component';
 import { StatistikFieldsFormService } from './statistik-fields.formservice';
 
@@ -18,12 +22,17 @@ import { StatistikFieldsFormService } from './statistik-fields.formservice';
     AdminSaveButtonComponent,
     AdminCancelButtonComponent,
     StatistikFieldsMappingsFormComponent,
+    SpinnerComponent,
+    AsyncPipe,
   ],
   providers: [{ provide: ADMIN_FORMSERVICE, useClass: StatistikFieldsFormService }],
 })
 export class StatistikFieldsFormComponent {
   public readonly formService = <StatistikFieldsFormService>inject(ADMIN_FORMSERVICE);
 
+  public readonly aggregationMappingStateResource$: Observable<StateResource<AggregationMappingResource>> =
+    this.formService.get();
+
   public readonly StatistikFieldsFormService = StatistikFieldsFormService;
   public readonly Routes = ROUTES;
 }
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.spec.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.spec.ts
index 2bb935d50ef36a1f94a13b522dd2d1e9c4f42179..45f57f4befa81655cdf9ceead88734d1586edb44 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.spec.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.spec.ts
@@ -26,8 +26,11 @@ import { createStateResource, EMPTY_STRING, StateResource } from '@alfa-client/t
 import { Mock, mock } from '@alfa-client/test-utils';
 import { TestBed } from '@angular/core/testing';
 import { FormArray, FormControl, FormGroup } from '@angular/forms';
+import { expect } from '@jest/globals';
 import { createAggregationMapping, createAggregationMappingResource } from 'libs/admin/reporting-shared/test/aggregation-mapping';
+import { omit } from 'lodash-es';
 import { of } from 'rxjs';
+import { singleColdCompleted } from '../../../../../tech-shared/test/marbles';
 import { StatistikFieldsFormService } from './statistik-fields.formservice';
 
 describe('StatistikFieldsFormService', () => {
@@ -54,15 +57,26 @@ describe('StatistikFieldsFormService', () => {
 
     beforeEach(() => {
       service.create.mockReturnValue(of(stateResource));
+      service.save.mockReturnValue(of(stateResource));
     });
 
-    it('should call service', () => {
+    it('should create', () => {
+      formService.isPatch = jest.fn().mockReturnValue(false);
       formService.form = <any>createAggregationMapping();
 
       formService.submit();
 
       expect(service.create).toHaveBeenCalledWith(formService.form.value);
     });
+
+    it('should save', () => {
+      formService.isPatch = jest.fn().mockReturnValue(true);
+      formService.form = <any>createAggregationMapping();
+
+      formService.submit();
+
+      expect(service.save).toHaveBeenCalledWith(formService.form.value);
+    });
   });
 
   describe('add mapping', () => {
@@ -109,4 +123,39 @@ describe('StatistikFieldsFormService', () => {
       });
     });
   });
+
+  describe('get', () => {
+    const stateResource: StateResource<AggregationMappingResource> = createStateResource(createAggregationMappingResource());
+
+    beforeEach(() => {
+      service.getByCurrentUrl.mockReturnValue(of(stateResource));
+      formService._patchForm = jest.fn();
+    });
+
+    it('should get by current url', () => {
+      formService.get();
+
+      expect(service.getByCurrentUrl).toHaveBeenCalled();
+    });
+
+    it('should patch form', () => {
+      formService.get().subscribe();
+
+      expect(formService._patchForm).toHaveBeenCalledWith(stateResource.resource);
+    });
+
+    it('should emit state resource', () => {
+      expect(formService.get()).toBeObservable(singleColdCompleted(stateResource));
+    });
+  });
+
+  describe('patch form', () => {
+    const aggregationMappingResource: AggregationMappingResource = createAggregationMappingResource();
+
+    it('should patch', () => {
+      formService._patchForm(aggregationMappingResource);
+
+      expect(formService.form.value).toEqual(omit(aggregationMappingResource, '_links'));
+    });
+  });
 });
diff --git a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts
index 67ecb47a0b7b37eda30cbcb22e9c4ceaadbc921c..75d717dbc1c6290e86d95a5193a9ea99cf6d5384 100644
--- a/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts
+++ b/alfa-client/libs/admin/statistik/src/lib/statistik-fields-form/statistik-fields.formservice.ts
@@ -1,8 +1,8 @@
-import { AggregationMappingResource, AggregationMappingService } from '@admin-client/reporting-shared';
-import { AbstractFormService, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
+import { AggregationMappingResource, AggregationMappingService, FieldMapping } from '@admin-client/reporting-shared';
+import { AbstractFormService, EMPTY_STRING, isLoaded, StateResource } from '@alfa-client/tech-shared';
 import { inject, Injectable } from '@angular/core';
 import { FormArray, FormControl, FormGroup, UntypedFormGroup } from '@angular/forms';
-import { Observable } from 'rxjs';
+import { filter, Observable, tap } from 'rxjs';
 
 @Injectable()
 export class StatistikFieldsFormService extends AbstractFormService<AggregationMappingResource> {
@@ -14,7 +14,7 @@ export class StatistikFieldsFormService extends AbstractFormService<AggregationM
   public static readonly FIELD_MAPPING_SOURCE_PATH = 'sourcePath';
   public static readonly FIELD_MAPPING_TARGET_PATH = 'targetPath';
 
-  private service = inject(AggregationMappingService);
+  private readonly aggregationMappingService = inject(AggregationMappingService);
 
   protected initForm(): UntypedFormGroup {
     return this.formBuilder.group({
@@ -28,7 +28,10 @@ export class StatistikFieldsFormService extends AbstractFormService<AggregationM
   }
 
   protected doSubmit(): Observable<StateResource<AggregationMappingResource>> {
-    return this.service.create(this.getFormValue());
+    if (this.isPatch()) {
+      return this.aggregationMappingService.save(this.getFormValue());
+    }
+    return this.aggregationMappingService.create(this.getFormValue());
   }
 
   protected getPathPrefix(): string {
@@ -39,10 +42,10 @@ export class StatistikFieldsFormService extends AbstractFormService<AggregationM
     this.mappings.push(this.createArrayControl());
   }
 
-  private createArrayControl(): FormGroup {
+  private createArrayControl(sourcePath: string = EMPTY_STRING, targetPath: string = EMPTY_STRING): FormGroup {
     return new FormGroup({
-      [StatistikFieldsFormService.FIELD_MAPPING_SOURCE_PATH]: new FormControl(EMPTY_STRING),
-      [StatistikFieldsFormService.FIELD_MAPPING_TARGET_PATH]: new FormControl(EMPTY_STRING),
+      [StatistikFieldsFormService.FIELD_MAPPING_SOURCE_PATH]: new FormControl(sourcePath),
+      [StatistikFieldsFormService.FIELD_MAPPING_TARGET_PATH]: new FormControl(targetPath),
     });
   }
 
@@ -53,4 +56,20 @@ export class StatistikFieldsFormService extends AbstractFormService<AggregationM
   public get mappings(): FormArray {
     return this.form.controls[StatistikFieldsFormService.FIELD_MAPPINGS] as FormArray;
   }
+
+  public get(): Observable<StateResource<AggregationMappingResource>> {
+    return this.aggregationMappingService.getByCurrentUrl().pipe(
+      filter(isLoaded),
+      tap((stateResource: StateResource<AggregationMappingResource>) => this._patchForm(stateResource.resource)),
+    );
+  }
+
+  _patchForm(value: AggregationMappingResource): void {
+    this.patch(value);
+    const mappingsFormArray: FormArray = this.form.controls[StatistikFieldsFormService.FIELD_MAPPINGS] as FormArray;
+    mappingsFormArray.clear();
+    value.mappings.forEach((mapping: FieldMapping) =>
+      mappingsFormArray.push(this.createArrayControl(mapping.sourcePath, mapping.targetPath)),
+    );
+  }
 }