diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts
index 9e7f485b57dde472449b84617e056c6590b56c67..0b7283732bb6d3096ed251d2281503016f739b93 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.model.ts
@@ -5,6 +5,7 @@ export enum BescheidStatus {
   DRAFT = 'DRAFT',
   SENT = 'SENT',
 }
+
 export interface Bescheid {
   status: BescheidStatus;
   beschiedenAm: string;
@@ -30,3 +31,13 @@ export interface UploadFileInProgress {
   fileName?: string;
   error?: HttpError;
 }
+
+export enum BescheidWizardStep {
+  AntragBescheiden = 1,
+  DokumenteHochladen = 2,
+  BescheidVersenden = 3,
+}
+
+export interface BescheidWizardDialogResult {
+  reloadVorgang: boolean;
+}
diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
index 4eb95c74da90efb1b6c868d02960da27fe81d28c..e36a84e4df075733f10c4bfce67483f094ca0daa 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
@@ -1,14 +1,5 @@
-import {
-  BinaryFileListResource,
-  BinaryFileResource,
-  BinaryFileService,
-} from '@alfa-client/binary-file-shared';
-import {
-  CommandOrder,
-  CommandResource,
-  CommandService,
-  CreateCommandProps,
-} from '@alfa-client/command-shared';
+import { BinaryFileListResource, BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared';
+import { CommandOrder, CommandResource, CommandService, CreateCommandProps } from '@alfa-client/command-shared';
 import {
   ApiError,
   EMPTY_ARRAY,
@@ -34,10 +25,7 @@ import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel';
 import { createApiError } from 'libs/tech-shared/test/error';
 import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
 import { Observable, of } from 'rxjs';
-import {
-  createBinaryFileListResource,
-  createBinaryFileResource,
-} from '../../../binary-file-shared/test/binary-file';
+import { createBinaryFileListResource, createBinaryFileResource } from '../../../binary-file-shared/test/binary-file';
 import {
   createCommandErrorResource,
   createCommandResource,
@@ -62,12 +50,14 @@ import {
   BescheidListResource,
   BescheidResource,
   BescheidStatus,
+  BescheidWizardStep,
   UploadFileInProgress,
 } from './bescheid.model';
 import { BescheidService } from './bescheid.service';
 import { DocumentLinkRel } from './document.linkrel';
 import { DocumentResource } from './document.model';
 
+import { PostfachService } from '@alfa-client/postfach-shared';
 import * as DateUtil from '../../../tech-shared/src/lib/date.util';
 import * as BescheidUtil from './bescheid.util';
 
@@ -80,20 +70,21 @@ describe('BescheidService', () => {
   let commandService: Mock<CommandService>;
   let vorgangCommandService: Mock<VorgangCommandService>;
   let binaryFileService: Mock<BinaryFileService>;
+  let postfachService: Mock<PostfachService>;
 
-  const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> =
-    createStateResource(createVorgangWithEingangResource());
+  const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = createStateResource(
+    createVorgangWithEingangResource(),
+  );
 
   beforeEach(() => {
     facade = mock(BescheidFacade);
     resourceRepository = mock(ResourceRepository);
     commandService = mock(CommandService);
     vorgangCommandService = mock(VorgangCommandService);
-
     vorgangService = mock(VorgangService);
     vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangWithEingangStateResource));
-
     binaryFileService = mock(BinaryFileService);
+    postfachService = mock(PostfachService);
 
     service = new BescheidService(
       useFromMock(facade),
@@ -102,6 +93,7 @@ describe('BescheidService', () => {
       useFromMock(vorgangCommandService),
       useFromMock(binaryFileService),
       useFromMock(resourceRepository),
+      useFromMock(postfachService),
     );
   });
 
@@ -109,10 +101,25 @@ describe('BescheidService', () => {
     expect(service).toBeTruthy();
   });
 
+  describe('getActiveStep', () => {
+    it('should emit initial value', () => {
+      const activeStep$: Observable<number> = service.getActiveStep();
+
+      expect(activeStep$).toBeObservable(singleCold(BescheidWizardStep.AntragBescheiden));
+    });
+  });
+
+  describe('setActiveStep', () => {
+    it('should emit changed active step', () => {
+      service.setActiveStep(BescheidWizardStep.DokumenteHochladen);
+
+      expect(service.activeStep$).toBeObservable(singleCold(BescheidWizardStep.DokumenteHochladen));
+    });
+  });
+
   describe('get bescheid draft', () => {
     const bescheidDraft: BescheidResource = createBescheidResource();
-    const bescheidDraftStateResource: StateResource<BescheidResource> =
-      createStateResource(bescheidDraft);
+    const bescheidDraftStateResource: StateResource<BescheidResource> = createStateResource(bescheidDraft);
 
     it('should call resource service', () => {
       service.bescheidResourceService.get = jest.fn();
@@ -123,12 +130,9 @@ describe('BescheidService', () => {
     });
 
     it('should return value', () => {
-      service.bescheidResourceService.get = jest
-        .fn()
-        .mockReturnValue(singleCold(bescheidDraftStateResource));
+      service.bescheidResourceService.get = jest.fn().mockReturnValue(singleCold(bescheidDraftStateResource));
 
-      const bescheidStateResource$: Observable<StateResource<BescheidResource>> =
-        service.getBescheidDraft();
+      const bescheidStateResource$: Observable<StateResource<BescheidResource>> = service.getBescheidDraft();
 
       expect(bescheidStateResource$).toBeObservable(singleCold(bescheidDraftStateResource));
     });
@@ -172,21 +176,17 @@ describe('BescheidService', () => {
 
   describe('bescheidErstellungUeberspringen', () => {
     describe('Bescheid Draft exists', () => {
-      const vorgangWithEingangResource: VorgangWithEingangResource =
-        createVorgangWithEingangResource();
+      const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
 
       const bescheidResource: BescheidResource = createBescheidResource();
-      const bescheidStateResource: StateResource<BescheidResource> =
-        createStateResource(bescheidResource);
+      const bescheidStateResource: StateResource<BescheidResource> = createStateResource(bescheidResource);
 
       const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
 
       beforeEach(() => {
         service.existsBescheidDraft = jest.fn().mockReturnValue(true);
         service.getBescheidDraft = jest.fn().mockReturnValue(of(bescheidStateResource));
-        service.bescheidLoeschenUndErstellungUeberspringen = jest
-          .fn()
-          .mockReturnValue(of(commandStateResource));
+        service.bescheidLoeschenUndErstellungUeberspringen = jest.fn().mockReturnValue(of(commandStateResource));
       });
 
       it('should get bescheid draft', (done) => {
@@ -221,8 +221,7 @@ describe('BescheidService', () => {
     });
 
     describe('Bescheid Draft not exists', () => {
-      const vorgangWithEingangResource: VorgangWithEingangResource =
-        createVorgangWithEingangResource();
+      const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
       const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
 
       beforeEach(() => {
@@ -254,9 +253,7 @@ describe('BescheidService', () => {
     let bescheidStateResource: StateResource<BescheidResource>;
 
     beforeEach(() => {
-      vorgangStateResource = createStateResource(
-        createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT]),
-      );
+      vorgangStateResource = createStateResource(createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT]));
       bescheidStateResource = createBescheidStateResource();
       vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangStateResource));
       service.getBescheidDraft = jest.fn().mockReturnValue(of(bescheidStateResource));
@@ -269,35 +266,27 @@ describe('BescheidService', () => {
     });
 
     it('should emit state resources', () => {
-      const bescheid$: Observable<StateResource<BescheidResource>> =
-        service.getBescheidDraftIfExists();
+      const bescheid$: Observable<StateResource<BescheidResource>> = service.getBescheidDraftIfExists();
 
-      expect(bescheid$).toBeObservable(
-        cold('(ab|)', { a: createEmptyStateResource(), b: bescheidStateResource }),
-      );
+      expect(bescheid$).toBeObservable(cold('(ab|)', { a: createEmptyStateResource(), b: bescheidStateResource }));
     });
   });
 
   describe('bescheidLoeschenUndErstellungUeberspringen', () => {
-    const vorgangWithEingangResource: VorgangWithEingangResource =
-      createVorgangWithEingangResource();
+    const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
     const bescheidResource: BescheidResource = createBescheidResource();
-    const vorgangAbschliessenCommandStateResource: StateResource<CommandResource> =
-      createCommandStateResource();
+    const vorgangAbschliessenCommandStateResource: StateResource<CommandResource> = createCommandStateResource();
 
     beforeEach(() => {
-      service.vorgangAbschliesen = jest
-        .fn()
-        .mockReturnValue(of(vorgangAbschliessenCommandStateResource));
+      service.vorgangAbschliesen = jest.fn().mockReturnValue(of(vorgangAbschliessenCommandStateResource));
       service.deleteBescheid = jest.fn().mockReturnValue(of(createCommandStateResource));
     });
 
     it('should Bescheiderstellung überspringen', (done) => {
-      const command$: Observable<StateResource<CommandResource>> =
-        service.bescheidLoeschenUndErstellungUeberspringen(
-          vorgangWithEingangResource,
-          bescheidResource,
-        );
+      const command$: Observable<StateResource<CommandResource>> = service.bescheidLoeschenUndErstellungUeberspringen(
+        vorgangWithEingangResource,
+        bescheidResource,
+      );
 
       command$.subscribe(() => {
         expect(service.vorgangAbschliesen).toHaveBeenCalledWith(vorgangWithEingangResource);
@@ -306,15 +295,12 @@ describe('BescheidService', () => {
     });
 
     it('should Bescheid löschen', (done) => {
-      service.vorgangAbschliesen = jest
-        .fn()
-        .mockReturnValue(of(createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE])));
-
-      const command$: Observable<StateResource<CommandResource>> =
-        service.bescheidLoeschenUndErstellungUeberspringen(
-          vorgangWithEingangResource,
-          bescheidResource,
-        );
+      service.vorgangAbschliesen = jest.fn().mockReturnValue(of(createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE])));
+
+      const command$: Observable<StateResource<CommandResource>> = service.bescheidLoeschenUndErstellungUeberspringen(
+        vorgangWithEingangResource,
+        bescheidResource,
+      );
 
       command$.subscribe(() => {
         expect(service.deleteBescheid).toHaveBeenCalledWith(bescheidResource);
@@ -325,11 +311,10 @@ describe('BescheidService', () => {
     it('should not Bescheid löschen', (done) => {
       service.vorgangAbschliesen = jest.fn().mockReturnValue(of(createCommandStateResource()));
 
-      const command$: Observable<StateResource<CommandResource>> =
-        service.bescheidLoeschenUndErstellungUeberspringen(
-          vorgangWithEingangResource,
-          bescheidResource,
-        );
+      const command$: Observable<StateResource<CommandResource>> = service.bescheidLoeschenUndErstellungUeberspringen(
+        vorgangWithEingangResource,
+        bescheidResource,
+      );
 
       command$.subscribe(() => {
         expect(service.deleteBescheid).not.toHaveBeenCalledWith(bescheidResource);
@@ -338,19 +323,17 @@ describe('BescheidService', () => {
     });
 
     it('should emit vorgang abschliessen command', () => {
-      const command$: Observable<StateResource<CommandResource>> =
-        service.bescheidLoeschenUndErstellungUeberspringen(
-          vorgangWithEingangResource,
-          bescheidResource,
-        );
+      const command$: Observable<StateResource<CommandResource>> = service.bescheidLoeschenUndErstellungUeberspringen(
+        vorgangWithEingangResource,
+        bescheidResource,
+      );
 
       expect(command$).toBeObservable(cold('(a|)', { a: vorgangAbschliessenCommandStateResource }));
     });
   });
 
   describe('vorgang abschliessen', () => {
-    const vorgangWithEingangResource: VorgangWithEingangResource =
-      createVorgangWithEingangResource();
+    const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
     const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
 
     beforeEach(() => {
@@ -358,9 +341,7 @@ describe('BescheidService', () => {
     });
 
     it('should call vorgang command service', (done) => {
-      const command$: Observable<StateResource<CommandResource>> = service.vorgangAbschliesen(
-        vorgangWithEingangResource,
-      );
+      const command$: Observable<StateResource<CommandResource>> = service.vorgangAbschliesen(vorgangWithEingangResource);
 
       command$.subscribe(() => {
         expect(vorgangCommandService.abschliessen).toHaveBeenCalledWith(vorgangWithEingangResource);
@@ -369,9 +350,7 @@ describe('BescheidService', () => {
     });
 
     it('should return command', () => {
-      const command$: Observable<StateResource<CommandResource>> = service.vorgangAbschliesen(
-        vorgangWithEingangResource,
-      );
+      const command$: Observable<StateResource<CommandResource>> = service.vorgangAbschliesen(vorgangWithEingangResource);
 
       expect(command$).toBeObservable(cold('(a|)', { a: commandStateResource }));
     });
@@ -399,8 +378,7 @@ describe('BescheidService', () => {
       const commandStateResource: StateResource<CommandResource> = createEmptyStateResource();
       commandService.createCommandByProps.mockReturnValue(commandStateResource);
 
-      const createdCommand: Observable<StateResource<CommandResource>> =
-        service.deleteBescheid(bescheidResource);
+      const createdCommand: Observable<StateResource<CommandResource>> = service.deleteBescheid(bescheidResource);
 
       expect(createdCommand).toEqual(commandStateResource);
     });
@@ -408,11 +386,8 @@ describe('BescheidService', () => {
 
   describe('update bescheid', () => {
     const bescheid: Bescheid = createBescheid();
-    const commandResource: CommandResource = createCommandResource([
-      CommandLinkRel.EFFECTED_RESOURCE,
-    ]);
-    const commandStateResource: StateResource<CommandResource> =
-      createStateResource(commandResource);
+    const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]);
+    const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource);
     const createCommandProps: CreateCommandProps = createCreateCommandProps();
     let buildUpdateBescheidCommandPropsSpy: jest.SpyInstance;
 
@@ -428,10 +403,7 @@ describe('BescheidService', () => {
     it('should build update bescheid command props', () => {
       service.updateBescheid(bescheid);
 
-      expect(buildUpdateBescheidCommandPropsSpy).toHaveBeenCalledWith(
-        service.getResource(),
-        bescheid,
-      );
+      expect(buildUpdateBescheidCommandPropsSpy).toHaveBeenCalledWith(service.getResource(), bescheid);
     });
 
     it('should create command', () => {
@@ -441,21 +413,18 @@ describe('BescheidService', () => {
     });
 
     it('should return command', () => {
-      const updateBescheid$: Observable<StateResource<CommandResource>> =
-        service.updateBescheid(bescheid);
+      const updateBescheid$: Observable<StateResource<CommandResource>> = service.updateBescheid(bescheid);
 
       expect(updateBescheid$).toBeObservable(cold('(a|)', { a: commandStateResource }));
     });
 
     it('should set resource by uri', (done) => {
-      service
-        .updateBescheid(bescheid)
-        .subscribe((commandStateResource: StateResource<CommandResource>) => {
-          expect(service.bescheidResourceService.loadByResourceUri).toHaveBeenCalledWith(
-            getUrl(commandStateResource.resource, CommandLinkRel.EFFECTED_RESOURCE),
-          );
-          done();
-        });
+      service.updateBescheid(bescheid).subscribe((commandStateResource: StateResource<CommandResource>) => {
+        expect(service.bescheidResourceService.loadByResourceUri).toHaveBeenCalledWith(
+          getUrl(commandStateResource.resource, CommandLinkRel.EFFECTED_RESOURCE),
+        );
+        done();
+      });
     });
 
     it('should clear create bescheid document in progress', (done) => {
@@ -495,9 +464,7 @@ describe('BescheidService', () => {
     let buildSendBescheidCommandPropsSpy: jest.SpyInstance;
 
     beforeEach(() => {
-      service.bescheidResourceService.get = jest
-        .fn()
-        .mockReturnValue(of(createStateResource(bescheidResource)));
+      service.bescheidResourceService.get = jest.fn().mockReturnValue(of(createStateResource(bescheidResource)));
       buildSendBescheidCommandPropsSpy = jest
         .spyOn(BescheidUtil, 'buildSendBescheidCommandProps')
         .mockReturnValue(createCommandProps);
@@ -525,10 +492,7 @@ describe('BescheidService', () => {
     });
 
     it('should return command', () => {
-      const command$: Observable<StateResource<CommandResource>> = service.sendBescheid(
-        bescheidResource,
-        linkRel,
-      );
+      const command$: Observable<StateResource<CommandResource>> = service.sendBescheid(bescheidResource, linkRel);
 
       expect(command$).toBeObservable(cold('(a|)', { a: commandStateResource }));
     });
@@ -545,15 +509,11 @@ describe('BescheidService', () => {
     it('should call sendBescheid', () => {
       service.sendBescheidManually(bescheidResource);
 
-      expect(service.sendBescheid).toHaveBeenCalledWith(
-        bescheidResource,
-        BescheidLinkRel.BESCHEIDEN,
-      );
+      expect(service.sendBescheid).toHaveBeenCalledWith(bescheidResource, BescheidLinkRel.BESCHEIDEN);
     });
 
     it('should return command', () => {
-      const command$: Observable<StateResource<CommandResource>> =
-        service.sendBescheidManually(bescheidResource);
+      const command$: Observable<StateResource<CommandResource>> = service.sendBescheidManually(bescheidResource);
 
       expect(command$).toBeObservable(singleColdCompleted(sendBescheidCommand));
     });
@@ -570,15 +530,11 @@ describe('BescheidService', () => {
     it('should call sendBescheid', () => {
       service.sendBescheidToAntragsteller(bescheidResource);
 
-      expect(service.sendBescheid).toHaveBeenCalledWith(
-        bescheidResource,
-        BescheidLinkRel.BESCHEIDEN_UND_SENDEN,
-      );
+      expect(service.sendBescheid).toHaveBeenCalledWith(bescheidResource, BescheidLinkRel.BESCHEIDEN_UND_SENDEN);
     });
 
     it('should return command', () => {
-      const command$: Observable<StateResource<CommandResource>> =
-        service.sendBescheidToAntragsteller(bescheidResource);
+      const command$: Observable<StateResource<CommandResource>> = service.sendBescheidToAntragsteller(bescheidResource);
 
       expect(command$).toBeObservable(singleColdCompleted(sendBescheidCommand));
     });
@@ -619,9 +575,7 @@ describe('BescheidService', () => {
 
     beforeEach(() => {
       bescheidResource = createBescheidResource([BescheidLinkRel.ATTACHMENTS]);
-      service.getBescheidDraft = jest
-        .fn()
-        .mockReturnValue(of(createStateResource(bescheidResource)));
+      service.getBescheidDraft = jest.fn().mockReturnValue(of(createStateResource(bescheidResource)));
 
       binaryFileResource = createBinaryFileResource();
 
@@ -631,10 +585,7 @@ describe('BescheidService', () => {
 
     it('should get files', (done) => {
       service.getAttachments().subscribe(() => {
-        expect(binaryFileService.getFiles).toHaveBeenCalledWith(
-          bescheidResource,
-          BescheidLinkRel.ATTACHMENTS,
-        );
+        expect(binaryFileService.getFiles).toHaveBeenCalledWith(bescheidResource, BescheidLinkRel.ATTACHMENTS);
         done();
       });
     });
@@ -664,8 +615,7 @@ describe('BescheidService', () => {
   describe('get bescheid document file', () => {
     it('should return value', (done) => {
       const binaryFile: BinaryFileResource = createBinaryFileResource();
-      const binaryFileStateResource: StateResource<BinaryFileResource> =
-        createStateResource(binaryFile);
+      const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(binaryFile);
       service.bescheidDocumentFile$.next(binaryFileStateResource);
 
       service.getBescheidDocumentFile().subscribe((result: StateResource<BinaryFileResource>) => {
@@ -706,13 +656,11 @@ describe('BescheidService', () => {
     });
 
     it('should return bescheid document file', (done) => {
-      service
-        .uploadBescheidDocument(bescheid, file)
-        .subscribe((uploadFileInProgress: UploadFileInProgress) => {
-          expect(uploadFileInProgress.fileName).toBe(file.name);
-          expect(uploadFileInProgress.loading).toBeTruthy();
-          done();
-        });
+      service.uploadBescheidDocument(bescheid, file).subscribe((uploadFileInProgress: UploadFileInProgress) => {
+        expect(uploadFileInProgress.fileName).toBe(file.name);
+        expect(uploadFileInProgress.loading).toBeTruthy();
+        done();
+      });
     });
   });
 
@@ -720,9 +668,7 @@ describe('BescheidService', () => {
     const bescheid: BescheidResource = createBescheidResource();
     const file: File = createFile();
 
-    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(
-      createBinaryFileResource(),
-    );
+    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource());
 
     beforeEach(() => {
       binaryFileService.uploadFile.mockReturnValue(of(binaryFileStateResource));
@@ -731,12 +677,7 @@ describe('BescheidService', () => {
     it('should call binary file service', () => {
       service.doUploadBescheidDocument(bescheid, file);
 
-      expect(binaryFileService.uploadFile).toHaveBeenCalledWith(
-        bescheid,
-        BescheidLinkRel.UPLOAD_BESCHEID_FILE,
-        file,
-        false,
-      );
+      expect(binaryFileService.uploadFile).toHaveBeenCalledWith(bescheid, BescheidLinkRel.UPLOAD_BESCHEID_FILE, file, false);
     });
 
     it('should call handle upload becheid document response', () => {
@@ -744,10 +685,7 @@ describe('BescheidService', () => {
 
       service.doUploadBescheidDocument(bescheid, file);
 
-      expect(service.handleUploadBescheidDocumentResponse).toHaveBeenCalledWith(
-        bescheid,
-        binaryFileStateResource,
-      );
+      expect(service.handleUploadBescheidDocumentResponse).toHaveBeenCalledWith(bescheid, binaryFileStateResource);
     });
   });
 
@@ -756,10 +694,8 @@ describe('BescheidService', () => {
 
     const binaryFile: BinaryFileResource = createBinaryFileResource();
     const apiError: ApiError = createApiError();
-    const binaryFileErrorStateResource: StateResource<BinaryFileResource> =
-      createErrorStateResource(apiError);
-    const binaryFileStateResource: StateResource<BinaryFileResource> =
-      createStateResource(binaryFile);
+    const binaryFileErrorStateResource: StateResource<BinaryFileResource> = createErrorStateResource(apiError);
+    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(binaryFile);
 
     it('should call create bescheid document from file on success', () => {
       service.createBescheidDocumentFromFile = jest.fn();
@@ -813,10 +749,7 @@ describe('BescheidService', () => {
     it('should build create command document from file props', () => {
       service.createBescheidDocumentFromFile(bescheid, binaryFile);
 
-      expect(buildCreateBescheidDocumentFromFilePropsSpy).toHaveBeenCalledWith(
-        bescheid,
-        binaryFile,
-      );
+      expect(buildCreateBescheidDocumentFromFilePropsSpy).toHaveBeenCalledWith(bescheid, binaryFile);
     });
 
     it('should call handle create bescheid document from file response', () => {
@@ -824,10 +757,7 @@ describe('BescheidService', () => {
 
       service.createBescheidDocumentFromFile(bescheid, binaryFile);
 
-      expect(service.handleCreateBescheidDocumentFromFileResponse).toHaveBeenCalledWith(
-        commandStateResource,
-        binaryFile,
-      );
+      expect(service.handleCreateBescheidDocumentFromFileResponse).toHaveBeenCalledWith(commandStateResource, binaryFile);
     });
   });
 
@@ -849,8 +779,7 @@ describe('BescheidService', () => {
     describe('on error', () => {
       it('should set upload bescheid in progress error', () => {
         const httpError: HttpError = createApiError();
-        const errorStateResource: StateResource<CommandResource> =
-          createErrorStateResource(httpError);
+        const errorStateResource: StateResource<CommandResource> = createErrorStateResource(httpError);
 
         service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, binaryFile);
 
@@ -859,8 +788,7 @@ describe('BescheidService', () => {
 
       it('should set upload bescheid in progress loading false', () => {
         const httpError: HttpError = createApiError();
-        const errorStateResource: StateResource<CommandResource> =
-          createErrorStateResource(httpError);
+        const errorStateResource: StateResource<CommandResource> = createErrorStateResource(httpError);
 
         service.handleCreateBescheidDocumentFromFileResponse(errorStateResource, binaryFile);
 
@@ -878,9 +806,7 @@ describe('BescheidService', () => {
       it('should set document uri', () => {
         service.handleCreateBescheidDocumentFromFileResponse(commandStateResource, binaryFile);
 
-        expect(service.bescheidDocumentUri$.value).toEqual(
-          getUrl(command, CommandLinkRel.EFFECTED_RESOURCE),
-        );
+        expect(service.bescheidDocumentUri$.value).toEqual(getUrl(command, CommandLinkRel.EFFECTED_RESOURCE));
       });
     });
   });
@@ -921,42 +847,39 @@ describe('BescheidService', () => {
     it('should emit empty state resource document file', () => {
       service.init();
 
-      expect(service.getBescheidDocumentFile()).toBeObservable(
-        singleCold(createEmptyStateResource()),
-      );
+      expect(service.getBescheidDocumentFile()).toBeObservable(singleCold(createEmptyStateResource()));
     });
 
     it('should emit empty state resource uploaded attachment', () => {
       service.init();
 
-      expect(service.getUploadedAttachment()).toBeObservable(
-        singleCold(createEmptyStateResource()),
-      );
+      expect(service.getUploadedAttachment()).toBeObservable(singleCold(createEmptyStateResource()));
     });
 
     it('should emit empty upload in progress for upload bescheid document in progress', () => {
       service.init();
 
-      expect(service.getUploadBescheidDocumentInProgress()).toBeObservable(
-        singleCold({ loading: false }),
-      );
+      expect(service.getUploadBescheidDocumentInProgress()).toBeObservable(singleCold({ loading: false }));
     });
 
     it('should emit empty upload in progress for upload attachmentdocument in progress', () => {
       service.init();
 
-      expect(service.getUploadAttachmentInProgress()).toBeObservable(
-        singleCold({ loading: false }),
-      );
+      expect(service.getUploadAttachmentInProgress()).toBeObservable(singleCold({ loading: false }));
+    });
+
+    it('should init active step', () => {
+      service.setActiveStep(2);
+
+      service.init();
+
+      expect(service.activeStep$).toBeObservable(singleCold(1));
     });
   });
 
   describe('create bescheid document', () => {
-    const commandResource: CommandResource = createCommandResource([
-      CommandLinkRel.EFFECTED_RESOURCE,
-    ]);
-    const commandStateResource: StateResource<CommandResource> =
-      createStateResource(commandResource);
+    const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]);
+    const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource);
 
     const bescheidResource: BescheidResource = createBescheidResource();
     const createCommandProps: CreateCommandProps = createCreateCommandProps();
@@ -1008,9 +931,7 @@ describe('BescheidService', () => {
         service.createBescheidDocument();
         tick();
 
-        expect(service.loadBescheidDocumentByUri).toHaveBeenCalledWith(
-          getUrl(commandResource, CommandLinkRel.EFFECTED_RESOURCE),
-        );
+        expect(service.loadBescheidDocumentByUri).toHaveBeenCalledWith(getUrl(commandResource, CommandLinkRel.EFFECTED_RESOURCE));
       }));
 
       it('should update bescheid document Url', fakeAsync(() => {
@@ -1019,16 +940,12 @@ describe('BescheidService', () => {
         service.createBescheidDocument();
         tick();
 
-        expect(service.bescheidDocumentUri$.value).toBe(
-          getUrl(commandResource, CommandLinkRel.EFFECTED_RESOURCE),
-        );
+        expect(service.bescheidDocumentUri$.value).toBe(getUrl(commandResource, CommandLinkRel.EFFECTED_RESOURCE));
       }));
     });
 
     describe('on error', () => {
-      const commandErrorStateResource: StateResource<CommandResource> = createStateResource(
-        createCommandErrorResource(),
-      );
+      const commandErrorStateResource: StateResource<CommandResource> = createStateResource(createCommandErrorResource());
 
       it('should emit command state resource', () => {
         commandService.createCommandByProps.mockReturnValue(of(commandErrorStateResource));
@@ -1071,8 +988,7 @@ describe('BescheidService', () => {
 
   describe('get bescheid document command', () => {
     const commandResource: CommandResource = createCommandResource();
-    const commandStateResource: StateResource<CommandResource> =
-      createStateResource(commandResource);
+    const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource);
 
     beforeEach(() => {
       commandService.getCommandByOrder.mockReturnValue(of(commandStateResource));
@@ -1080,9 +996,7 @@ describe('BescheidService', () => {
 
     it('should call command service', (done) => {
       service.getBescheidDocumentCommand().subscribe(() => {
-        expect(commandService.getCommandByOrder).toHaveBeenCalledWith(
-          CommandOrder.CREATE_BESCHEID_DOCUMENT,
-        );
+        expect(commandService.getCommandByOrder).toHaveBeenCalledWith(CommandOrder.CREATE_BESCHEID_DOCUMENT);
         done();
       });
     });
@@ -1175,9 +1089,7 @@ describe('BescheidService', () => {
 
   describe('load bescheid document file', () => {
     const document: DocumentResource = createDocumentResource([DocumentLinkRel.FILE]);
-    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(
-      createBinaryFileResource(),
-    );
+    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource());
 
     beforeEach(() => {
       binaryFileService.getFile.mockReturnValue(of(binaryFileStateResource));
@@ -1186,9 +1098,7 @@ describe('BescheidService', () => {
     it('should call bianry file service', () => {
       service.loadBescheidDocumentFile(document);
 
-      expect(binaryFileService.getFile).toHaveBeenCalledWith(
-        getUrl(document, DocumentLinkRel.FILE),
-      );
+      expect(binaryFileService.getFile).toHaveBeenCalledWith(getUrl(document, DocumentLinkRel.FILE));
     });
 
     it('should set bescheidDocument file', () => {
@@ -1217,11 +1127,8 @@ describe('BescheidService', () => {
 
     it('should return value', () => {
       const bescheidList: BescheidListResource = createBescheidListResource();
-      const bescheidListStateResource: StateResource<BescheidListResource> =
-        createStateResource(bescheidList);
-      service.bescheidListResourceService.getList = jest
-        .fn()
-        .mockReturnValue(singleCold(bescheidListStateResource));
+      const bescheidListStateResource: StateResource<BescheidListResource> = createStateResource(bescheidList);
+      service.bescheidListResourceService.getList = jest.fn().mockReturnValue(singleCold(bescheidListStateResource));
 
       const command$: Observable<StateResource<BescheidListResource>> = service.getBescheidList();
 
@@ -1244,8 +1151,7 @@ describe('BescheidService', () => {
     });
 
     it('should return value', () => {
-      const documentStateResource$: Observable<StateResource<DocumentResource>> =
-        service.loadBescheidDocument(resourceUri);
+      const documentStateResource$: Observable<StateResource<DocumentResource>> = service.loadBescheidDocument(resourceUri);
 
       expect(documentStateResource$).toBeObservable(
         cold('(ab|)', { a: createEmptyStateResource(true), b: createStateResource(document) }),
@@ -1255,13 +1161,10 @@ describe('BescheidService', () => {
 
   describe('get resource', () => {
     const bescheidResource: BescheidResource = createBescheidResource();
-    const bescheidStateResource: StateResource<BescheidResource> =
-      createStateResource(bescheidResource);
+    const bescheidStateResource: StateResource<BescheidResource> = createStateResource(bescheidResource);
 
     it('should call bescheid resource service select resource', () => {
-      service.bescheidResourceService.selectResource = jest
-        .fn()
-        .mockReturnValue(of(bescheidStateResource));
+      service.bescheidResourceService.selectResource = jest.fn().mockReturnValue(of(bescheidStateResource));
 
       service.getResource();
 
@@ -1269,9 +1172,7 @@ describe('BescheidService', () => {
     });
 
     it('should return value', () => {
-      service.bescheidResourceService.selectResource = jest
-        .fn()
-        .mockReturnValue(of(bescheidStateResource));
+      service.bescheidResourceService.selectResource = jest.fn().mockReturnValue(of(bescheidStateResource));
 
       const bescheidDraft: BescheidResource = service.getResource();
 
@@ -1281,8 +1182,7 @@ describe('BescheidService', () => {
 
   describe('getEmpfaenger', () => {
     it('should return Empfänger', () => {
-      const vorgangWithEingangResource: VorgangWithEingangResource =
-        createVorgangWithEingangResource();
+      const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
       const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> =
         createStateResource(vorgangWithEingangResource);
       vorgangService.getVorgangWithEingang.mockReturnValue(of(vorgangWithEingangStateResource));
@@ -1306,12 +1206,8 @@ describe('BescheidService', () => {
 
     beforeEach(() => {
       service.filterBySentStatus = jest.fn().mockReturnValue(bescheide);
-      sortByGermanDateStrSpy = jest
-        .spyOn(DateUtil, 'sortByGermanDateStr')
-        .mockReturnValue(bescheide);
-      getItemsSpy = service.bescheidListResourceService.getItems = jest
-        .fn()
-        .mockReturnValue(of(bescheide));
+      sortByGermanDateStrSpy = jest.spyOn(DateUtil, 'sortByGermanDateStr').mockReturnValue(bescheide);
+      getItemsSpy = service.bescheidListResourceService.getItems = jest.fn().mockReturnValue(of(bescheide));
     });
 
     it('should get items', () => {
@@ -1350,9 +1246,7 @@ describe('BescheidService', () => {
     beforeEach(() => {
       service.getBescheidList = jest.fn().mockReturnValue(of(bescheidListStateResource));
       service.filterBySentStatus = jest.fn().mockReturnValue(bescheide);
-      getItemsSpy = service.bescheidListResourceService.getItems = jest
-        .fn()
-        .mockReturnValue(of(bescheide));
+      getItemsSpy = service.bescheidListResourceService.getItems = jest.fn().mockReturnValue(of(bescheide));
     });
 
     it('should get items', () => {
@@ -1389,9 +1283,7 @@ describe('BescheidService', () => {
         status: BescheidStatus.SENT,
       };
 
-      const filteredBescheide: BescheidResource[] = service.filterBySentStatus([
-        bescheidWithSentStatus,
-      ]);
+      const filteredBescheide: BescheidResource[] = service.filterBySentStatus([bescheidWithSentStatus]);
 
       expect(filteredBescheide.length).toBe(1);
     });
@@ -1402,9 +1294,7 @@ describe('BescheidService', () => {
         status: BescheidStatus.DRAFT,
       };
 
-      const filteredBescheide: BescheidResource[] = service.filterBySentStatus([
-        bescheidWithDraftStatus,
-      ]);
+      const filteredBescheide: BescheidResource[] = service.filterBySentStatus([bescheidWithDraftStatus]);
 
       expect(filteredBescheide.length).toBe(0);
     });
@@ -1427,13 +1317,9 @@ describe('BescheidService', () => {
   });
 
   describe('uploadAttachment', () => {
-    const bescheidResource: BescheidResource = createBescheidResource([
-      BescheidLinkRel.UPLOAD_ATTACHMENT,
-    ]);
+    const bescheidResource: BescheidResource = createBescheidResource([BescheidLinkRel.UPLOAD_ATTACHMENT]);
     const file: File = createFile();
-    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(
-      createBinaryFileResource(),
-    );
+    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource());
 
     beforeEach(() => {
       binaryFileService.uploadFile.mockReturnValue(of(binaryFileStateResource));
@@ -1450,12 +1336,7 @@ describe('BescheidService', () => {
 
     it('should upload file', (done) => {
       service.uploadAttachment(bescheidResource, file).subscribe(() => {
-        expect(binaryFileService.uploadFile).toBeCalledWith(
-          bescheidResource,
-          BescheidLinkRel.UPLOAD_ATTACHMENT,
-          file,
-          false,
-        );
+        expect(binaryFileService.uploadFile).toBeCalledWith(bescheidResource, BescheidLinkRel.UPLOAD_ATTACHMENT, file, false);
         done();
       });
     });
@@ -1468,16 +1349,13 @@ describe('BescheidService', () => {
     });
 
     it('should emit uploaded binary file', () => {
-      expect(service.uploadAttachment(bescheidResource, file)).toBeObservable(
-        singleColdCompleted(binaryFileStateResource),
-      );
+      expect(service.uploadAttachment(bescheidResource, file)).toBeObservable(singleColdCompleted(binaryFileStateResource));
     });
   });
 
   describe('handleAttachmentUpload', () => {
     describe('on error', () => {
-      const binaryFileStateResource: StateResource<BinaryFileResource> =
-        createErrorStateResource(createApiError());
+      const binaryFileStateResource: StateResource<BinaryFileResource> = createErrorStateResource(createApiError());
 
       it('should emit upload in progress', () => {
         service.handleAttachmentUpload(binaryFileStateResource);
@@ -1498,9 +1376,7 @@ describe('BescheidService', () => {
     });
 
     describe('on success', () => {
-      const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(
-        createBinaryFileResource(),
-      );
+      const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(createBinaryFileResource());
 
       it('should emit upload in progress', () => {
         service.handleAttachmentUpload(binaryFileStateResource);
@@ -1529,4 +1405,26 @@ describe('BescheidService', () => {
       expect(service.uploadAttachmentInProgress$.value).toEqual(createEmptyStateResource());
     });
   });
+
+  describe('exit', () => {
+    it('should refresh bescheid list', () => {
+      service.bescheidListResourceService.refresh = jest.fn();
+
+      service.exit();
+
+      expect(service.bescheidListResourceService.refresh).toHaveBeenCalled();
+    });
+
+    it('should reload current vorgang', () => {
+      service.exit();
+
+      expect(vorgangService.reloadCurrentVorgang).toHaveBeenCalled();
+    });
+
+    it('should reload postfach list', () => {
+      service.exit();
+
+      expect(postfachService.setPostfachMailOnReload).toHaveBeenCalled();
+    });
+  });
 });
diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
index 277891fe474da829e8b3c8adacdcbf233fee73ee..8c76ba58973ec05b98571d86ee1e26da368c5db7 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
@@ -1,8 +1,4 @@
-import {
-  BinaryFileListLinkRel,
-  BinaryFileResource,
-  BinaryFileService,
-} from '@alfa-client/binary-file-shared';
+import { BinaryFileListLinkRel, BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared';
 import {
   CommandOrder,
   CommandResource,
@@ -12,20 +8,21 @@ import {
   notHasCommandError,
   tapOnCommandSuccessfullyDone,
 } from '@alfa-client/command-shared';
+import { PostfachService } from '@alfa-client/postfach-shared';
 import {
+  EMPTY_ARRAY,
+  HttpError,
+  ResourceListService,
+  StateResource,
   createEmptyStateResource,
   createStateResource,
-  EMPTY_ARRAY,
   filterIsLoadedOrHasError,
   getEmbeddedResources,
   hasStateResourceError,
-  HttpError,
   isLoaded,
   isNotEmpty,
   isNotNil,
-  ResourceListService,
   sortByGermanDateStr,
-  StateResource,
 } from '@alfa-client/tech-shared';
 import {
   VorgangCommandService,
@@ -35,23 +32,9 @@ import {
 } from '@alfa-client/vorgang-shared';
 import { getEmpfaenger } from '@alfa-client/vorgang-shared-ui';
 import { Injectable } from '@angular/core';
-import { getUrl, hasLink, ResourceUri } from '@ngxp/rest';
-import {
-  BehaviorSubject,
-  filter,
-  first,
-  map,
-  Observable,
-  startWith,
-  Subscription,
-  switchMap,
-  take,
-  tap,
-} from 'rxjs';
-import {
-  ListResourceServiceConfig,
-  ResourceServiceConfig,
-} from '../../../tech-shared/src/lib/resource/resource.model';
+import { ResourceUri, getUrl, hasLink } from '@ngxp/rest';
+import { BehaviorSubject, Observable, Subscription, filter, first, map, startWith, switchMap, take, tap } from 'rxjs';
+import { ListResourceServiceConfig, ResourceServiceConfig } from '../../../tech-shared/src/lib/resource/resource.model';
 import { ResourceRepository } from '../../../tech-shared/src/lib/resource/resource.repository';
 import { ResourceService } from '../../../tech-shared/src/lib/resource/resource.service';
 import { BescheidFacade } from './+state/bescheid.facade';
@@ -61,6 +44,7 @@ import {
   BescheidListResource,
   BescheidResource,
   BescheidStatus,
+  BescheidWizardStep,
   UploadFileInProgress,
 } from './bescheid.model';
 import {
@@ -76,38 +60,38 @@ import { DocumentResource } from './document.model';
 
 @Injectable({ providedIn: 'root' })
 export class BescheidService {
+  readonly activeStep$: BehaviorSubject<BescheidWizardStep> = new BehaviorSubject(BescheidWizardStep.AntragBescheiden);
+
   bescheidResourceService: ResourceService<VorgangWithEingangResource, BescheidResource>;
-  bescheidListResourceService: ResourceListService<
-    VorgangWithEingangResource,
-    BescheidListResource,
-    BescheidResource
-  >;
+  bescheidListResourceService: ResourceListService<VorgangWithEingangResource, BescheidListResource, BescheidResource>;
 
-  readonly bescheidDocumentFile$: BehaviorSubject<StateResource<BinaryFileResource>> =
-    new BehaviorSubject<StateResource<BinaryFileResource>>(createEmptyStateResource());
+  readonly bescheidDocumentFile$: BehaviorSubject<StateResource<BinaryFileResource>> = new BehaviorSubject<
+    StateResource<BinaryFileResource>
+  >(createEmptyStateResource());
 
-  readonly bescheidDocumentUri$: BehaviorSubject<ResourceUri> = new BehaviorSubject<ResourceUri>(
-    null,
-  );
+  readonly bescheidDocumentUri$: BehaviorSubject<ResourceUri> = new BehaviorSubject<ResourceUri>(null);
 
-  readonly bescheidDocument$: BehaviorSubject<StateResource<DocumentResource>> =
-    new BehaviorSubject<StateResource<DocumentResource>>(createEmptyStateResource());
+  readonly bescheidDocument$: BehaviorSubject<StateResource<DocumentResource>> = new BehaviorSubject<
+    StateResource<DocumentResource>
+  >(createEmptyStateResource());
 
-  readonly bescheidList$: BehaviorSubject<StateResource<BescheidListResource>> =
-    new BehaviorSubject(createEmptyStateResource<BescheidListResource>());
+  readonly bescheidList$: BehaviorSubject<StateResource<BescheidListResource>> = new BehaviorSubject(
+    createEmptyStateResource<BescheidListResource>(),
+  );
 
-  readonly createBescheidDocumentInProgress$: BehaviorSubject<StateResource<CommandResource>> =
-    new BehaviorSubject<StateResource<CommandResource>>(createEmptyStateResource());
+  readonly createBescheidDocumentInProgress$: BehaviorSubject<StateResource<CommandResource>> = new BehaviorSubject<
+    StateResource<CommandResource>
+  >(createEmptyStateResource());
 
-  readonly uploadBescheidDocumentInProgress$: BehaviorSubject<UploadFileInProgress> =
-    new BehaviorSubject<UploadFileInProgress>({ loading: false });
+  readonly uploadBescheidDocumentInProgress$: BehaviorSubject<UploadFileInProgress> = new BehaviorSubject<UploadFileInProgress>({
+    loading: false,
+  });
 
-  readonly uploadAttachmentInProgress$: BehaviorSubject<UploadFileInProgress> = new BehaviorSubject(
-    { loading: false },
-  );
+  readonly uploadAttachmentInProgress$: BehaviorSubject<UploadFileInProgress> = new BehaviorSubject({ loading: false });
 
-  readonly uploadedAttachment$: BehaviorSubject<StateResource<BinaryFileResource>> =
-    new BehaviorSubject(createEmptyStateResource());
+  readonly uploadedAttachment$: BehaviorSubject<StateResource<BinaryFileResource>> = new BehaviorSubject(
+    createEmptyStateResource(),
+  );
 
   loadBescheidDocumentSubscription: Subscription;
 
@@ -118,16 +102,22 @@ export class BescheidService {
     private readonly vorgangCommandService: VorgangCommandService,
     private readonly binaryFileService: BinaryFileService,
     private readonly repository: ResourceRepository,
+    private readonly postfachService: PostfachService,
   ) {
     this.bescheidResourceService = new CommandResourceService(
       this.buildBescheidDraftServiceConfig(),
       repository,
       this.commandService,
     );
-    this.bescheidListResourceService = new ResourceListService(
-      this.buildBescheidListServiceConfig(),
-      repository,
-    );
+    this.bescheidListResourceService = new ResourceListService(this.buildBescheidListServiceConfig(), repository);
+  }
+
+  public getActiveStep(): Observable<BescheidWizardStep> {
+    return this.activeStep$.asObservable();
+  }
+
+  public setActiveStep(step: BescheidWizardStep): void {
+    this.activeStep$.next(step);
   }
 
   buildBescheidDraftServiceConfig(): ResourceServiceConfig<VorgangWithEingangResource> {
@@ -158,6 +148,7 @@ export class BescheidService {
     this.uploadBescheidDocumentInProgress$.next({ loading: false });
     this.clearUploadAttachment();
     this.uploadAttachmentInProgress$.next({ loading: false });
+    this.activeStep$.next(BescheidWizardStep.AntragBescheiden);
   }
 
   public getBescheidDraft(): Observable<StateResource<BescheidResource>> {
@@ -190,10 +181,7 @@ export class BescheidService {
       filter(isLoaded),
       first(),
       switchMap((bescheidStateResource: StateResource<BescheidResource>) =>
-        this.bescheidLoeschenUndErstellungUeberspringen(
-          vorgangWithEingangResource,
-          bescheidStateResource.resource,
-        ),
+        this.bescheidLoeschenUndErstellungUeberspringen(vorgangWithEingangResource, bescheidStateResource.resource),
       ),
     );
   }
@@ -202,8 +190,7 @@ export class BescheidService {
     return this.vorgangService.getVorgangWithEingang().pipe(
       filter(
         (stateResource: StateResource<VorgangWithEingangResource>) =>
-          isLoaded(stateResource) &&
-          hasLink(stateResource.resource, VorgangWithEingangLinkRel.BESCHEID_DRAFT),
+          isLoaded(stateResource) && hasLink(stateResource.resource, VorgangWithEingangLinkRel.BESCHEID_DRAFT),
       ),
       switchMap(() => this.getBescheidDraft()),
       startWith(createEmptyStateResource<BescheidResource>()),
@@ -219,9 +206,7 @@ export class BescheidService {
     );
   }
 
-  vorgangAbschliesen(
-    vorgangWithEingangResource: VorgangWithEingangResource,
-  ): Observable<StateResource<CommandResource>> {
+  vorgangAbschliesen(vorgangWithEingangResource: VorgangWithEingangResource): Observable<StateResource<CommandResource>> {
     return this.vorgangCommandService.abschliessen(vorgangWithEingangResource);
   }
 
@@ -240,39 +225,25 @@ export class BescheidService {
     this.uploadedAttachment$.next(createEmptyStateResource());
   }
 
-  public sendBescheidToAntragsteller(
-    bescheidResource: BescheidResource,
-  ): Observable<StateResource<CommandResource>> {
+  public sendBescheidToAntragsteller(bescheidResource: BescheidResource): Observable<StateResource<CommandResource>> {
     return this.sendBescheid(bescheidResource, BescheidLinkRel.BESCHEIDEN_UND_SENDEN);
   }
 
-  public sendBescheidManually(
-    bescheidResource: BescheidResource,
-  ): Observable<StateResource<CommandResource>> {
+  public sendBescheidManually(bescheidResource: BescheidResource): Observable<StateResource<CommandResource>> {
     return this.sendBescheid(bescheidResource, BescheidLinkRel.BESCHEIDEN);
   }
 
-  sendBescheid(
-    bescheidResource: BescheidResource,
-    linkRel: string,
-  ): Observable<StateResource<CommandResource>> {
+  sendBescheid(bescheidResource: BescheidResource, linkRel: string): Observable<StateResource<CommandResource>> {
     return this.bescheidResourceService.get().pipe(
       filterIsLoadedOrHasError(),
       switchMap((stateResource: StateResource<BescheidResource>) =>
-        this.commandService.createCommandByProps(
-          buildSendBescheidCommandProps(stateResource.resource, linkRel),
-        ),
+        this.commandService.createCommandByProps(buildSendBescheidCommandProps(stateResource.resource, linkRel)),
       ),
     );
   }
 
-  doUpdateBescheid(
-    bescheidResource: BescheidResource,
-    bescheid: Bescheid,
-  ): Observable<StateResource<CommandResource>> {
-    return this.commandService.createCommandByProps(
-      buildUpdateBescheidCommandProps(bescheidResource, bescheid),
-    );
+  doUpdateBescheid(bescheidResource: BescheidResource, bescheid: Bescheid): Observable<StateResource<CommandResource>> {
+    return this.commandService.createCommandByProps(buildUpdateBescheidCommandProps(bescheidResource, bescheid));
   }
 
   private updateBescheidDraft(command: CommandResource): void {
@@ -284,13 +255,9 @@ export class BescheidService {
       filter(isLoaded),
       map((stateResource: StateResource<BescheidResource>) => stateResource.resource),
       filter((resource: BescheidResource) => hasLink(resource, BescheidLinkRel.ATTACHMENTS)),
-      switchMap((resource: BescheidResource) =>
-        this.binaryFileService.getFiles(resource, BescheidLinkRel.ATTACHMENTS),
-      ),
+      switchMap((resource: BescheidResource) => this.binaryFileService.getFiles(resource, BescheidLinkRel.ATTACHMENTS)),
       filter(isLoaded),
-      map((stateResource) =>
-        getEmbeddedResources<BinaryFileResource>(stateResource, BinaryFileListLinkRel.FILE_LIST),
-      ),
+      map((stateResource) => getEmbeddedResources<BinaryFileResource>(stateResource, BinaryFileListLinkRel.FILE_LIST)),
     );
   }
 
@@ -330,10 +297,7 @@ export class BescheidService {
     this.bescheidDocumentFile$.next({ ...this.bescheidDocumentFile$.value, loading: true });
   }
 
-  public uploadBescheidDocument(
-    bescheid: BescheidResource,
-    file: File,
-  ): Observable<UploadFileInProgress> {
+  public uploadBescheidDocument(bescheid: BescheidResource, file: File): Observable<UploadFileInProgress> {
     this.clearCreateBescheidDocumentInProgress();
     this.initUploadBescheidDocumentInProgress(file.name);
     this.doUploadBescheidDocument(bescheid, file);
@@ -429,14 +393,10 @@ export class BescheidService {
   }
 
   doCreateBescheidDocument(): Observable<StateResource<CommandResource>> {
-    return this.commandService.createCommandByProps(
-      buildCreateBescheidDocumentCommandProps(this.getResource()),
-    );
+    return this.commandService.createCommandByProps(buildCreateBescheidDocumentCommandProps(this.getResource()));
   }
 
-  private handleCreateBescheidDocumentResponse(
-    commandStateResource: StateResource<CommandResource>,
-  ): void {
+  private handleCreateBescheidDocumentResponse(commandStateResource: StateResource<CommandResource>): void {
     this.createBescheidDocumentInProgress$.next(commandStateResource);
     if (notHasCommandError(commandStateResource.resource)) {
       const documentUri: ResourceUri = getEffectedResourceUrl(commandStateResource.resource);
@@ -498,9 +458,7 @@ export class BescheidService {
     this.vorgangService.reloadCurrentVorgang();
   }
 
-  public loadBescheidDocument(
-    resourceUri: ResourceUri,
-  ): Observable<StateResource<DocumentResource>> {
+  public loadBescheidDocument(resourceUri: ResourceUri): Observable<StateResource<DocumentResource>> {
     return this.repository.getResource<DocumentResource>(resourceUri).pipe(
       map((documentResource: DocumentResource) => createStateResource(documentResource)),
       startWith(createEmptyStateResource<DocumentResource>(true)),
@@ -524,10 +482,7 @@ export class BescheidService {
   }
 
   private sortByBeschiedenAm(bescheide: BescheidResource[]): BescheidResource[] {
-    return sortByGermanDateStr<BescheidResource>(
-      bescheide,
-      (bescheid: BescheidResource) => bescheid.beschiedenAm,
-    );
+    return sortByGermanDateStr<BescheidResource>(bescheide, (bescheid: BescheidResource) => bescheid.beschiedenAm);
   }
 
   public existBescheid(): Observable<boolean> {
@@ -553,17 +508,12 @@ export class BescheidService {
     this.bescheidListResourceService.refresh();
   }
 
-  public uploadAttachment(
-    bescheidResource: BescheidResource,
-    file: File,
-  ): Observable<StateResource<BinaryFileResource>> {
+  public uploadAttachment(bescheidResource: BescheidResource, file: File): Observable<StateResource<BinaryFileResource>> {
     this.uploadAttachmentInProgress$.next({ fileName: file.name, loading: true });
     return this.binaryFileService
       .uploadFile(bescheidResource, BescheidLinkRel.UPLOAD_ATTACHMENT, file, false)
       .pipe(
-        tap((binaryFileStateResource: StateResource<BinaryFileResource>) =>
-          this.handleAttachmentUpload(binaryFileStateResource),
-        ),
+        tap((binaryFileStateResource: StateResource<BinaryFileResource>) => this.handleAttachmentUpload(binaryFileStateResource)),
       );
   }
 
@@ -593,4 +543,10 @@ export class BescheidService {
   public clearAttachmentUpload(): void {
     this.uploadAttachmentInProgress$.next(createEmptyStateResource());
   }
+
+  public exit(): void {
+    this.bescheidListResourceService.refresh();
+    this.vorgangService.reloadCurrentVorgang();
+    this.postfachService.setPostfachMailOnReload();
+  }
 }
diff --git a/alfa-client/libs/bescheid/src/index.ts b/alfa-client/libs/bescheid/src/index.ts
index 9f2c0268f34d8c2099f74dbb30ffae0bed8a8a21..d64bde358e1b807d3996ff5a31c233b0e80fb188 100644
--- a/alfa-client/libs/bescheid/src/index.ts
+++ b/alfa-client/libs/bescheid/src/index.ts
@@ -1,2 +1,3 @@
+export * from './lib/bescheid-wizard-container/bescheid-wizard-container.component';
 export * from './lib/bescheid.module';
 export * from './lib/beschieden-date-in-vorgang-container/beschieden-date-in-vorgang-container.component';
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.spec.ts
index b03163c947ea3ea59ea070eeb8ff9b651da1cd3c..2a5450489d1b8592cb1912e1a11390efe976db78 100644
--- a/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.spec.ts
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-in-vorgang-container/bescheid-in-vorgang/bescheid-in-vorgang.component.spec.ts
@@ -1,11 +1,8 @@
 import { BescheidResource } from '@alfa-client/bescheid-shared';
-import {
-  BinaryFile2ContainerComponent,
-  BinaryFileContainerComponent,
-} from '@alfa-client/binary-file';
+import { BinaryFile2ContainerComponent, BinaryFileContainerComponent } from '@alfa-client/binary-file';
 import { BinaryFileResource } from '@alfa-client/binary-file-shared';
 import { StateResource, createStateResource } from '@alfa-client/tech-shared';
-import { getElementFromFixture } from '@alfa-client/test-utils';
+import { existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils';
 import { ExpansionPanelComponent, SpinnerComponent } from '@alfa-client/ui';
 import { registerLocaleData } from '@angular/common';
 import localeDe from '@angular/common/locales/de';
@@ -26,16 +23,12 @@ describe('BescheidInVorgangComponent', () => {
   let fixture: ComponentFixture<BescheidInVorgangComponent>;
 
   const bescheidResource: BescheidResource = createBescheidResource();
-  const bescheidStateResource: StateResource<BescheidResource> =
-    createStateResource(bescheidResource);
+  const bescheidStateResource: StateResource<BescheidResource> = createStateResource(bescheidResource);
 
   const binaryFile: BinaryFileResource = createBinaryFileResource();
-  const binaryFileStateResource: StateResource<BinaryFileResource> =
-    createStateResource(binaryFile);
+  const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(binaryFile);
 
-  const bescheidDocumentBinaryFileContainer = getDataTestIdOf(
-    'bescheid-document-in-vorgang-binary-file',
-  );
+  const bescheidDocumentBinaryFileContainer: string = getDataTestIdOf('bescheid-document-in-vorgang-binary-file');
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
@@ -64,20 +57,18 @@ describe('BescheidInVorgangComponent', () => {
   describe('render', () => {
     it('should show bescheid document file', () => {
       component.bescheidDocumentFile = createStateResource(createBinaryFileResource());
-      fixture.detectChanges();
 
-      const element = getElementFromFixture(fixture, bescheidDocumentBinaryFileContainer);
+      fixture.detectChanges();
 
-      expect(element).toBeInstanceOf(HTMLElement);
+      existsAsHtmlElement(fixture, bescheidDocumentBinaryFileContainer);
     });
 
     it('should NOT show bescheid document file if resource null', () => {
       component.bescheidDocumentFile = { ...createStateResource(null), loaded: true };
-      fixture.detectChanges();
 
-      const element = getElementFromFixture(fixture, bescheidDocumentBinaryFileContainer);
+      fixture.detectChanges();
 
-      expect(element).not.toBeInstanceOf(HTMLElement);
+      notExistsAsHtmlElement(fixture, bescheidDocumentBinaryFileContainer);
     });
 
     it('should NOT show bescheid document file if resource loading', () => {
@@ -85,11 +76,10 @@ describe('BescheidInVorgangComponent', () => {
         ...createStateResource(createBinaryFileResource()),
         loaded: false,
       };
-      fixture.detectChanges();
 
-      const element = getElementFromFixture(fixture, bescheidDocumentBinaryFileContainer);
+      fixture.detectChanges();
 
-      expect(element).not.toBeInstanceOf(HTMLElement);
+      notExistsAsHtmlElement(fixture, bescheidDocumentBinaryFileContainer);
     });
   });
 
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/bescheid-list-in-vorgang.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/bescheid-list-in-vorgang.component.ts
index d8607e426d22e858d48673a678a3f593a2c32824..3ebd9ece73f85fe24a2817f27cef4df6acfd31b9 100644
--- a/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/bescheid-list-in-vorgang.component.ts
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-list-in-vorgang-container/bescheid-list-in-vorgang/bescheid-list-in-vorgang.component.ts
@@ -1,9 +1,4 @@
-import {
-  BescheidLinkRel,
-  BescheidListLinkRel,
-  BescheidListResource,
-  BescheidStatus,
-} from '@alfa-client/bescheid-shared';
+import { BescheidLinkRel, BescheidListLinkRel, BescheidListResource, BescheidStatus } from '@alfa-client/bescheid-shared';
 import { Component, Input } from '@angular/core';
 
 @Component({
@@ -12,7 +7,7 @@ import { Component, Input } from '@angular/core';
   styles: [],
 })
 export class BescheidListInVorgangComponent {
-  @Input() bescheidList: BescheidListResource;
+  @Input() public bescheidList: BescheidListResource;
 
   public readonly bescheidListLinkRel = BescheidListLinkRel;
   public readonly bescheidLinkRel = BescheidLinkRel;
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..47feee904d3ac5176801d46f6ef374184cb5cfcb
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.html
@@ -0,0 +1,30 @@
+<div class="relative z-10 duration-500 ease-in-out" aria-label="Bescheid Dialog" role="dialog" aria-modal="true">
+  <div class="fixed inset-0 z-10 w-screen overflow-y-auto">
+    <div class="flex h-full items-center justify-center p-8">
+      <div
+        class="relative h-full w-full max-w-7xl transform overflow-hidden rounded-lg bg-background-200 px-6 py-10 text-left shadow-xl transition-all"
+      >
+        <ng-container *ngIf="bescheidDraftStateResource$ | async as bescheidStateResource">
+          <ods-button
+            variant="icon"
+            size="fit"
+            class="absolute right-0 top-0 text-text"
+            (clickEmitter)="cancelWizard(bescheidStateResource.resource)"
+            data-test-id="close-bescheid"
+          >
+            <ods-close-icon icon />
+          </ods-button>
+          <alfa-bescheid-wizard
+            [vorgangWithEingangResource]="vorgangWithEingangResource"
+            [activeStep]="bescheidService.getActiveStep() | async"
+            [bescheidStateResource]="bescheidStateResource"
+            [submitStateResource]="submitStateResource$ | async"
+            (weiterClickEmitter)="onWeiter($event)"
+            (vorgangAbgeschlossen)="onVorgangAbgeschlossen()"
+            data-test-id="bescheid-wizard"
+          ></alfa-bescheid-wizard>
+        </ng-container>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e09cca2f663a659a867467375030620b111cb82b
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.spec.ts
@@ -0,0 +1,557 @@
+import { BescheidResource, BescheidService, BescheidWizardDialogResult, BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { CommandOrder, CommandResource } from '@alfa-client/command-shared';
+import {
+  ESCAPE_KEY,
+  StateResource,
+  createEmptyStateResource,
+  createErrorStateResource,
+  createStateResource,
+} from '@alfa-client/tech-shared';
+import {
+  DialogRefMock,
+  Mock,
+  createDialogRefMock,
+  existsAsHtmlElement,
+  getElementFromFixtureByType,
+  mock,
+  triggerEvent,
+  useFromMock,
+} from '@alfa-client/test-utils';
+import { OzgcloudDialogService } from '@alfa-client/ui';
+import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ButtonComponent, CloseIconComponent } from '@ods/system';
+import { MockComponent } from 'ng-mocks';
+import { EMPTY, of } from 'rxjs';
+import { createBescheidResource, createBescheidStateResource } from '../../../../bescheid-shared/src/test/bescheid';
+import {
+  createCommandErrorResource,
+  createCommandResource,
+  createSuccessfullyDoneCommandResource,
+  createSuccessfullyDoneCommandStateResource,
+} from '../../../../command-shared/test/command';
+import { getDataTestIdOf } from '../../../../tech-shared/test/data-test';
+import { createApiError } from '../../../../tech-shared/test/error';
+import { singleColdCompleted } from '../../../../tech-shared/test/marbles';
+import { createKeydownKeyboardEvent } from '../../../../test-utils/src/lib/keyboard';
+import { createVorgangWithEingangResource } from '../../../../vorgang-shared/test/vorgang';
+import { BescheidWizardContainerComponent } from './bescheid-wizard-container.component';
+import { BescheidWizardComponent } from './bescheid-wizard/bescheid-wizard.component';
+import {
+  BescheidWizardCancelDialogContainerComponent,
+  CancelWizardDialogData,
+  CancelWizardDialogResult,
+} from './bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component';
+import { BescheidFormService } from './bescheid.formservice';
+
+describe('BescheidWizardContainerComponent', () => {
+  let component: BescheidWizardContainerComponent;
+  let fixture: ComponentFixture<BescheidWizardContainerComponent>;
+
+  const bescheidWizard: string = getDataTestIdOf('bescheid-wizard');
+  const closeButton: string = getDataTestIdOf('close-bescheid');
+
+  let bescheidService: Mock<BescheidService>;
+  let ozgcloudDialogService: Mock<OzgcloudDialogService>;
+  let formService: Mock<BescheidFormService>;
+  let wizardDialogRef: DialogRefMock<BescheidWizardDialogResult>;
+
+  const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
+
+  beforeEach(() => {
+    bescheidService = mock(BescheidService);
+    ozgcloudDialogService = mock(OzgcloudDialogService);
+    formService = mock(BescheidFormService);
+    wizardDialogRef = createDialogRefMock();
+  });
+
+  beforeEach(async () => {
+    TestBed.overrideComponent(BescheidWizardContainerComponent, {
+      set: {
+        providers: [
+          {
+            provide: BescheidFormService,
+            useValue: formService,
+          },
+        ],
+      },
+    });
+
+    await TestBed.configureTestingModule({
+      declarations: [
+        BescheidWizardContainerComponent,
+        MockComponent(BescheidWizardComponent),
+        MockComponent(BescheidWizardCancelDialogContainerComponent),
+        MockComponent(ButtonComponent),
+        MockComponent(CloseIconComponent),
+      ],
+      providers: [
+        {
+          provide: DIALOG_DATA,
+          useValue: { vorgangWithEingangResource },
+        },
+        {
+          provide: BescheidService,
+          useValue: bescheidService,
+        },
+        {
+          provide: OzgcloudDialogService,
+          useValue: ozgcloudDialogService,
+        },
+        {
+          provide: DialogRef,
+          useValue: wizardDialogRef,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardContainerComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('component', () => {
+    describe('constructor', () => {
+      it('should set vorgang with eingang resource from dialog data', () => {
+        expect(component.vorgangWithEingangResource).toBe(vorgangWithEingangResource);
+      });
+    });
+
+    describe('ngOnInit', () => {
+      it('should init service', () => {
+        component.ngOnInit();
+
+        expect(bescheidService.init).toHaveBeenCalled();
+      });
+
+      it('should set vorgang with eingang on form service', () => {
+        formService.setVorgangWithEingangResource = jest.fn();
+
+        component.ngOnInit();
+
+        expect(formService.setVorgangWithEingangResource).toHaveBeenCalledWith(vorgangWithEingangResource);
+      });
+
+      it('should subscribe to bescheid resource', () => {
+        component.subscribeToBescheidResourceIfExists = jest.fn();
+
+        component.ngOnInit();
+
+        expect(component.subscribeToBescheidResourceIfExists).toHaveBeenCalled();
+      });
+
+      it('should subscribe escape key handler', () => {
+        component.handleEscapeKey = jest.fn();
+
+        component.ngOnInit();
+
+        expect(component.handleEscapeKey).toHaveBeenCalled();
+      });
+    });
+
+    describe('subscribeToBescheidResourceIfExists', () => {
+      const bescheidDraftStateResource: StateResource<BescheidResource> = createBescheidStateResource();
+
+      beforeEach(() => {
+        bescheidService.getBescheidDraft.mockReturnValue(of(bescheidDraftStateResource));
+      });
+
+      describe('when bescheid draft link exist', () => {
+        beforeEach(() => {
+          component.vorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT]);
+        });
+
+        it('should get bescheid draft', () => {
+          component.subscribeToBescheidResourceIfExists();
+
+          expect(bescheidService.getBescheidDraft).toHaveBeenCalled();
+        });
+
+        it('should emit bescheid draft state resource', () => {
+          component.subscribeToBescheidResourceIfExists();
+
+          expect(component.bescheidDraftStateResource$).toBeObservable(singleColdCompleted(bescheidDraftStateResource));
+        });
+      });
+
+      describe('when bescheid draft link NOT exists', () => {
+        beforeEach(() => {
+          component.vorgangWithEingangResource = createVorgangWithEingangResource();
+        });
+
+        it('should not get bescheid draft', () => {
+          component.subscribeToBescheidResourceIfExists();
+
+          expect(bescheidService.getBescheidDraft).not.toHaveBeenCalled();
+        });
+
+        it('should emit empty bescheid draft state resource', () => {
+          component.subscribeToBescheidResourceIfExists();
+
+          expect(component.bescheidDraftStateResource$).toBeObservable(
+            singleColdCompleted(createEmptyStateResource<BescheidResource>()),
+          );
+        });
+
+        it('should not patch form values', () => {
+          formService.patchValues = jest.fn();
+
+          component.subscribeToBescheidResourceIfExists();
+
+          expect(formService.patchValues).not.toHaveBeenCalled();
+        });
+      });
+    });
+
+    describe('onWeiter', () => {
+      beforeEach(() => {
+        formService.submit = jest.fn().mockReturnValue(of(createSuccessfullyDoneCommandStateResource()));
+        component.isBescheidSuccessfullyCreated = jest.fn().mockReturnValue(true);
+        bescheidService.getBescheidDraft.mockReturnValue(of(createBescheidStateResource()));
+      });
+
+      it('should submit form', () => {
+        component.onWeiter(BescheidWizardStep.DokumenteHochladen);
+
+        expect(formService.submit).toHaveBeenCalled();
+      });
+
+      it('should increment step on created bescheid', () => {
+        component.onWeiter(BescheidWizardStep.DokumenteHochladen);
+
+        component.submitStateResource$.subscribe();
+        expect(bescheidService.setActiveStep).toHaveBeenCalledWith(BescheidWizardStep.DokumenteHochladen);
+      });
+
+      it('should increment step on updated bescheid', () => {
+        component.isBescheidSuccessfullyCreated = jest.fn().mockReturnValue(false);
+
+        component.onWeiter(BescheidWizardStep.DokumenteHochladen);
+
+        component.submitStateResource$.subscribe();
+        expect(bescheidService.setActiveStep).toHaveBeenCalledWith(BescheidWizardStep.DokumenteHochladen);
+      });
+
+      it('should not increment step on command resource error', () => {
+        component.isBescheidSuccessfullyCreated = jest.fn().mockReturnValue(false);
+        formService.submit = jest.fn().mockReturnValue(of(createErrorStateResource(createApiError())));
+
+        component.onWeiter(BescheidWizardStep.DokumenteHochladen);
+
+        component.submitStateResource$.subscribe();
+        expect(bescheidService.setActiveStep).not.toHaveBeenCalled();
+      });
+
+      it('should not increment step on command resource loading', () => {
+        component.isBescheidSuccessfullyCreated = jest.fn().mockReturnValue(false);
+        formService.submit = jest.fn().mockReturnValue(of(createStateResource(createCommandResource(), true)));
+
+        component.onWeiter(BescheidWizardStep.DokumenteHochladen);
+
+        component.submitStateResource$.subscribe();
+        expect(bescheidService.setActiveStep).not.toHaveBeenCalled();
+      });
+
+      it('should not increment step on bescheid resource error', () => {
+        bescheidService.getBescheidDraft.mockReturnValue(of(createErrorStateResource(createApiError())));
+
+        component.onWeiter(BescheidWizardStep.DokumenteHochladen);
+
+        component.submitStateResource$.subscribe();
+        expect(bescheidService.setActiveStep).not.toHaveBeenCalled();
+      });
+
+      it('should not increment step on bescheid loading', () => {
+        bescheidService.getBescheidDraft.mockReturnValue(of(createStateResource(null, true)));
+
+        component.onWeiter(BescheidWizardStep.DokumenteHochladen);
+
+        component.submitStateResource$.subscribe();
+        expect(bescheidService.setActiveStep).not.toHaveBeenCalled();
+      });
+    });
+
+    describe('isBescheidSuccessfullyCreated', () => {
+      it('should return true', () => {
+        const createBescheidCommandResource: CommandResource = {
+          ...createSuccessfullyDoneCommandResource(),
+          order: CommandOrder.CREATE_BESCHEID,
+        };
+        const isBescheidSuccessfullyCreated: boolean = component.isBescheidSuccessfullyCreated(createBescheidCommandResource);
+
+        expect(isBescheidSuccessfullyCreated).toBeTruthy();
+      });
+
+      it('should return false on different order', () => {
+        const createBescheidCommandResource: CommandResource = {
+          ...createSuccessfullyDoneCommandResource(),
+          order: CommandOrder.UPDATE_BESCHEID,
+        };
+        const isBescheidSuccessfullyCreated: boolean = component.isBescheidSuccessfullyCreated(createBescheidCommandResource);
+
+        expect(isBescheidSuccessfullyCreated).toBeFalsy();
+      });
+
+      it('should return false on error command', () => {
+        const createBescheidCommandResource: CommandResource = createCommandErrorResource();
+        const isBescheidSuccessfullyCreated: boolean = component.isBescheidSuccessfullyCreated(createBescheidCommandResource);
+
+        expect(isBescheidSuccessfullyCreated).toBeFalsy();
+      });
+    });
+
+    describe('cancelWizard', () => {
+      beforeEach(() => {
+        component.openCancelDialog = jest.fn();
+        component.subscribeToCancelDialogClosed = jest.fn();
+      });
+
+      it('should open cancel dialog', () => {
+        const bescheidResource: BescheidResource = createBescheidResource();
+
+        component.cancelWizard(bescheidResource);
+
+        expect(component.openCancelDialog).toHaveBeenCalledWith(bescheidResource);
+      });
+
+      it('should NOT open cancel dialog', () => {
+        component.cancelDialogRef = createDialogRefMock() as any;
+        const bescheidResource: BescheidResource = createBescheidResource();
+
+        component.cancelWizard(bescheidResource);
+
+        expect(component.openCancelDialog).not.toHaveBeenCalled();
+      });
+
+      it('should handle dialog close', () => {
+        const bescheidResource: BescheidResource = createBescheidResource();
+
+        component.cancelWizard(bescheidResource);
+
+        expect(component.subscribeToCancelDialogClosed).toHaveBeenCalled();
+      });
+
+      it('should NOT handle dialog close', () => {
+        component.cancelDialogRef = createDialogRefMock() as any;
+        const bescheidResource: BescheidResource = createBescheidResource();
+
+        component.cancelWizard(bescheidResource);
+
+        expect(component.subscribeToCancelDialogClosed).not.toHaveBeenCalled();
+      });
+    });
+
+    describe('openCancelDialog', () => {
+      it('should show close dialog', () => {
+        const bescheidResource: BescheidResource = createBescheidResource();
+        ozgcloudDialogService.openInCallingComponentContext.mockReturnValue({
+          closed: EMPTY,
+        });
+
+        component.openCancelDialog(bescheidResource);
+
+        expect(ozgcloudDialogService.openInCallingComponentContext).toHaveBeenCalledWith(
+          BescheidWizardCancelDialogContainerComponent,
+          component.viewContainerRef,
+          {
+            bescheidResource,
+          } as CancelWizardDialogData,
+        );
+      });
+
+      it('should set cancelDialogRef', () => {
+        const bescheidResource: BescheidResource = createBescheidResource();
+        ozgcloudDialogService.openInCallingComponentContext.mockReturnValue({
+          closed: EMPTY,
+        });
+
+        component.openCancelDialog(bescheidResource);
+
+        expect(component.cancelDialogRef).toBeDefined();
+      });
+    });
+
+    describe('subscribeToCancelDialogClosed', () => {
+      let cancelDialogResult: CancelWizardDialogResult;
+
+      beforeEach(() => {
+        cancelDialogResult = { closeWizard: true };
+        component.cancelDialogRef = { ...createDialogRefMock(), closed: of(cancelDialogResult) } as any;
+        component.handleCancelDialogClosed = jest.fn();
+      });
+
+      it('should handle cancel dialog closed', () => {
+        component.subscribeToCancelDialogClosed();
+
+        expect(component.handleCancelDialogClosed).toHaveBeenCalledWith(cancelDialogResult);
+      });
+    });
+
+    describe('handleCancelDialogClosed', () => {
+      it('should unset cancelDialogRef', () => {
+        component.cancelDialogRef = useFromMock(mock(DialogRef<CancelWizardDialogResult>));
+
+        component.handleCancelDialogClosed({ closeWizard: true });
+
+        expect(component.cancelDialogRef).toBeNull();
+      });
+
+      it('should close wizard', () => {
+        component.handleCancelDialogClosed({ closeWizard: true });
+
+        expect(wizardDialogRef.close).toHaveBeenCalledWith({ reloadVorgang: true });
+      });
+
+      it('should NOT close wizard', () => {
+        component.handleCancelDialogClosed({ closeWizard: false });
+
+        expect(wizardDialogRef.close).not.toHaveBeenCalled();
+      });
+
+      it('should NOT close wizard on empty result', () => {
+        component.handleCancelDialogClosed(null);
+
+        expect(wizardDialogRef.close).not.toHaveBeenCalled();
+      });
+    });
+
+    describe('handleEscapeKey', () => {
+      beforeEach(() => {
+        component.cancelWizard = jest.fn();
+      });
+
+      it('should close wizard if bescheid resource loaded', () => {
+        const bescheidResource: BescheidResource = createBescheidResource();
+        component.bescheidDraftStateResource$ = of(createStateResource(bescheidResource));
+        wizardDialogRef.keydownEvents = of(createKeydownKeyboardEvent(ESCAPE_KEY));
+
+        component.handleEscapeKey();
+
+        expect(component.cancelWizard).toHaveBeenCalledWith(bescheidResource);
+      });
+
+      it('should close wizard if bescheid resource not exists', () => {
+        component.bescheidDraftStateResource$ = of(createEmptyStateResource<BescheidResource>());
+        wizardDialogRef.keydownEvents = of(createKeydownKeyboardEvent(ESCAPE_KEY));
+
+        component.handleEscapeKey();
+
+        expect(component.cancelWizard).toHaveBeenCalledWith(null);
+      });
+
+      it('should not close if no escape key pressed', () => {
+        const bescheidResource: BescheidResource = createBescheidResource();
+        component.bescheidDraftStateResource$ = of(createStateResource(bescheidResource));
+        wizardDialogRef.keydownEvents = of(createKeydownKeyboardEvent('a'));
+
+        component.handleEscapeKey();
+
+        expect(component.cancelWizard).not.toHaveBeenCalled();
+      });
+
+      it('should not close if bescheid resource loading', () => {
+        const bescheidResource: BescheidResource = createBescheidResource();
+        component.bescheidDraftStateResource$ = of(createStateResource(bescheidResource, true));
+        wizardDialogRef.keydownEvents = of(createKeydownKeyboardEvent(ESCAPE_KEY));
+
+        component.handleEscapeKey();
+
+        expect(component.cancelWizard).not.toHaveBeenCalled();
+      });
+    });
+
+    describe('onVorgangAbgeschlossen', () => {
+      it('should close wizard', () => {
+        component.onVorgangAbgeschlossen();
+
+        expect(wizardDialogRef.close).toHaveBeenCalled();
+      });
+    });
+  });
+
+  describe('template', () => {
+    describe('alfa-bescheid-wizard', () => {
+      function getElementComponent(): BescheidWizardComponent {
+        return getElementFromFixtureByType(fixture, BescheidWizardComponent);
+      }
+
+      describe('input', () => {
+        it('should set vorgangWithEingangResource', () => {
+          component.vorgangWithEingangResource = createVorgangWithEingangResource();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().vorgangWithEingangResource).toBe(component.vorgangWithEingangResource);
+        });
+
+        it('should set activeStep', () => {
+          bescheidService.getActiveStep.mockReturnValue(of(2));
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().activeStep).toBe(2);
+        });
+
+        it('should set bescheidStateResource', () => {
+          const bescheidStateResource: StateResource<BescheidResource> = createBescheidStateResource();
+          component.bescheidDraftStateResource$ = of(bescheidStateResource);
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().bescheidStateResource).toBe(bescheidStateResource);
+        });
+      });
+
+      describe('output', () => {
+        it('should call onWeiter', () => {
+          component.onWeiter = jest.fn();
+
+          triggerEvent({
+            fixture,
+            name: 'weiterClickEmitter',
+            elementSelector: bescheidWizard,
+          });
+
+          expect(component.onWeiter).toHaveBeenCalled();
+        });
+
+        it('should call onVorgangAbgeschlossen', () => {
+          component.onVorgangAbgeschlossen = jest.fn();
+
+          triggerEvent({
+            fixture,
+            name: 'vorgangAbgeschlossen',
+            elementSelector: bescheidWizard,
+          });
+
+          expect(component.onVorgangAbgeschlossen).toHaveBeenCalled();
+        });
+      });
+    });
+
+    describe('ods-button close', () => {
+      it('should show', () => {
+        existsAsHtmlElement(fixture, closeButton);
+      });
+
+      describe('output', () => {
+        it('should call cancelWizard', () => {
+          component.cancelWizard = jest.fn();
+
+          triggerEvent({
+            fixture,
+            name: 'clickEmitter',
+            elementSelector: closeButton,
+          });
+
+          expect(component.cancelWizard).toHaveBeenCalled();
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e9ed187540a5921430c404a9a7a3d3020e0e70bd
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard-container.component.ts
@@ -0,0 +1,138 @@
+import { BescheidResource, BescheidService, BescheidWizardDialogResult, BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { CommandOrder, CommandResource, isSuccessfulDone } from '@alfa-client/command-shared';
+import {
+  StateResource,
+  createEmptyStateResource,
+  hasStateResourceError,
+  isEscapeKey,
+  isLoaded,
+  isNotLoading,
+  isNotNil,
+} from '@alfa-client/tech-shared';
+import { OzgcloudDialogService } from '@alfa-client/ui';
+import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
+import { Component, Inject, OnDestroy, OnInit, ViewContainerRef } from '@angular/core';
+import { Resource, hasLink } from '@ngxp/rest';
+import { Observable, Subscription, filter, first, of, switchMap, tap } from 'rxjs';
+import {
+  BescheidWizardCancelDialogContainerComponent,
+  CancelWizardDialogData,
+  CancelWizardDialogResult,
+} from './bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component';
+import { BescheidFormService } from './bescheid.formservice';
+
+export interface BescheidWizardDialogData {
+  vorgangWithEingangResource: VorgangWithEingangResource;
+}
+
+@Component({
+  selector: 'alfa-bescheid-wizard-container',
+  templateUrl: './bescheid-wizard-container.component.html',
+  providers: [BescheidFormService],
+})
+export class BescheidWizardContainerComponent implements OnInit, OnDestroy {
+  public bescheidDraftStateResource$: Observable<StateResource<BescheidResource>> =
+    of(createEmptyStateResource<BescheidResource>());
+  public submitStateResource$: Observable<StateResource<Resource>> = of(createEmptyStateResource<Resource>());
+
+  cancelDialogRef: DialogRef<CancelWizardDialogResult>;
+  vorgangWithEingangResource: VorgangWithEingangResource;
+  keydownEventsSubscription: Subscription;
+
+  constructor(
+    @Inject(DIALOG_DATA) private readonly dialogData: BescheidWizardDialogData,
+    private readonly dialogRef: DialogRef<BescheidWizardDialogResult>,
+    readonly viewContainerRef: ViewContainerRef,
+    public readonly formService: BescheidFormService,
+    readonly bescheidService: BescheidService,
+    private readonly ozgcloudDialogService: OzgcloudDialogService,
+  ) {
+    this.vorgangWithEingangResource = dialogData.vorgangWithEingangResource;
+  }
+
+  ngOnInit(): void {
+    this.bescheidService.init();
+    this.formService.setVorgangWithEingangResource(this.vorgangWithEingangResource);
+    this.subscribeToBescheidResourceIfExists();
+    this.handleEscapeKey();
+  }
+
+  ngOnDestroy(): void {
+    this.keydownEventsSubscription.unsubscribe();
+  }
+
+  subscribeToBescheidResourceIfExists(): void {
+    if (hasLink(this.vorgangWithEingangResource, VorgangWithEingangLinkRel.BESCHEID_DRAFT)) {
+      this.bescheidDraftStateResource$ = this.bescheidService.getBescheidDraft();
+    }
+  }
+
+  handleEscapeKey(): void {
+    this.keydownEventsSubscription = this.dialogRef.keydownEvents
+      .pipe(
+        filter(isEscapeKey),
+        switchMap(() => this.bescheidDraftStateResource$),
+        filter(isNotLoading),
+      )
+      .subscribe((bescheidStateResource: StateResource<BescheidResource>) => {
+        this.cancelWizard(bescheidStateResource.resource);
+      });
+  }
+
+  public onWeiter(nextStep: BescheidWizardStep): void {
+    this.submitStateResource$ = this.formService.submit().pipe(
+      switchMap((commandStateResource: StateResource<CommandResource>) => {
+        if (this.isBescheidSuccessfullyCreated(commandStateResource.resource)) {
+          this.bescheidDraftStateResource$ = this.bescheidService.getBescheidDraft();
+          return this.bescheidDraftStateResource$;
+        }
+        return of(commandStateResource);
+      }),
+      tap((stateResource: StateResource<Resource>) => {
+        if (isLoaded(stateResource) && !hasStateResourceError(stateResource)) {
+          this.bescheidService.setActiveStep(nextStep);
+        }
+      }),
+    );
+  }
+
+  isBescheidSuccessfullyCreated(commandResource: CommandResource): boolean {
+    return isSuccessfulDone(commandResource) && commandResource.order === CommandOrder.CREATE_BESCHEID;
+  }
+
+  public cancelWizard(bescheidResource: BescheidResource): void {
+    if (isNotNil(this.cancelDialogRef)) return;
+    this.openCancelDialog(bescheidResource);
+    this.subscribeToCancelDialogClosed();
+  }
+
+  openCancelDialog(bescheidResource: BescheidResource) {
+    const dialogData: CancelWizardDialogData = {
+      bescheidResource,
+    };
+
+    this.cancelDialogRef = this.ozgcloudDialogService.openInCallingComponentContext(
+      BescheidWizardCancelDialogContainerComponent,
+      this.viewContainerRef,
+      dialogData,
+    );
+  }
+
+  subscribeToCancelDialogClosed() {
+    this.cancelDialogRef.closed
+      .pipe(first())
+      .subscribe((result: CancelWizardDialogResult) => this.handleCancelDialogClosed(result));
+  }
+
+  handleCancelDialogClosed(closeResult: CancelWizardDialogResult): void {
+    this.cancelDialogRef = null;
+    if (isNotNil(closeResult) && closeResult.closeWizard) {
+      this.dialogRef.close({ reloadVorgang: true });
+    }
+  }
+
+  public onVorgangAbgeschlossen(): void {
+    this.dialogRef.close();
+  }
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..9e9a62b72411f5926b2753c20eb2126957b0c626
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.html
@@ -0,0 +1,7 @@
+<button
+  (click)="onClick()"
+  data-test-id="bescheid-ueberspringen"
+  class="mt-6 select-none text-left text-primary hover:underline"
+>
+  Bescheiderstellung überspringen<br />und abschließen
+</button>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3e627c499b0e4c4718fa60bdae4d29fe0641ec48
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.spec.ts
@@ -0,0 +1,130 @@
+import {
+  createDialogRefMock,
+  DialogRefMock,
+  existsAsHtmlElement,
+  mock,
+  Mock,
+  triggerEvent,
+  useFromMock,
+} from '@alfa-client/test-utils';
+import { OzgcloudDialogService } from '@alfa-client/ui';
+import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { EventEmitter } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { of } from 'rxjs';
+import { createSuccessfullyDoneCommandStateResource } from '../../../../../../command-shared/test/command';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import {
+  createDialogResult,
+  OzgcloudDialogCommandResult,
+} from '../../../../../../ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result';
+import { createVorgangWithEingangResource } from '../../../../../../vorgang-shared/test/vorgang';
+import {
+  AbschliessenDialogData,
+  BescheidWizardAbschliessenDialogContainerComponent,
+} from '../abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component';
+import { BescheidWizardAbschliessenButtonComponent } from './bescheid-wizard-abschliessen-button.component';
+
+describe('BescheidWizardAbschliessenButtonComponent', () => {
+  let component: BescheidWizardAbschliessenButtonComponent;
+  let fixture: ComponentFixture<BescheidWizardAbschliessenButtonComponent>;
+
+  const abschliessenButton: string = getDataTestIdOf('bescheid-ueberspringen');
+
+  let ozgcloudDialogService: Mock<OzgcloudDialogService>;
+
+  beforeEach(() => {
+    ozgcloudDialogService = mock(OzgcloudDialogService);
+  });
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardAbschliessenButtonComponent],
+      providers: [
+        {
+          provide: OzgcloudDialogService,
+          useValue: ozgcloudDialogService,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardAbschliessenButtonComponent);
+    component = fixture.componentInstance;
+    component.vorgangAbgeschlossen = useFromMock(mock(EventEmitter<void>));
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('component', () => {
+    describe('onClick', () => {
+      beforeEach(() => {
+        component.handleDialogClosed = jest.fn();
+      });
+
+      it('should open dialog', () => {
+        const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
+        component.vorgangWithEingangResource = vorgangWithEingangResource;
+
+        component.onClick();
+
+        expect(ozgcloudDialogService.openInCallingComponentContext).toHaveBeenCalledWith(
+          BescheidWizardAbschliessenDialogContainerComponent,
+          component.viewContainerRef,
+          { vorgangWithEingangResource } as AbschliessenDialogData,
+        );
+      });
+
+      it('should handle dialog closed', () => {
+        const dialogRef: DialogRefMock<OzgcloudDialogCommandResult> = createDialogRefMock();
+        ozgcloudDialogService.openInCallingComponentContext.mockReturnValue(dialogRef);
+
+        component.onClick();
+
+        expect(component.handleDialogClosed).toHaveBeenCalledWith(dialogRef);
+      });
+    });
+  });
+
+  describe('handleDialogClosed', () => {
+    let dialogRef: DialogRefMock<OzgcloudDialogCommandResult>;
+
+    beforeEach(() => {
+      dialogRef = createDialogRefMock();
+    });
+
+    it('should NOT emit vorgang abgeschlossen', () => {
+      dialogRef.closed = of(undefined);
+
+      component.handleDialogClosed(dialogRef as never);
+
+      expect(component.vorgangAbgeschlossen.emit).not.toHaveBeenCalled();
+    });
+
+    it('should emit vorgang abgeschlossen', () => {
+      dialogRef.closed = of(createDialogResult(createSuccessfullyDoneCommandStateResource()));
+
+      component.handleDialogClosed(dialogRef as never);
+
+      expect(component.vorgangAbgeschlossen.emit).toHaveBeenCalled();
+    });
+  });
+
+  describe('template', () => {
+    it('should have button', () => {
+      existsAsHtmlElement(fixture, abschliessenButton);
+    });
+
+    describe('output', () => {
+      it('should call onClick', () => {
+        component.onClick = jest.fn();
+
+        triggerEvent({ fixture, name: 'click', elementSelector: abschliessenButton });
+
+        expect(component.onClick).toHaveBeenCalled();
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5e04e99d2b1342e528148b124f613a044906965
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component.ts
@@ -0,0 +1,49 @@
+import { OzgcloudDialogService } from '@alfa-client/ui';
+import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { DialogRef } from '@angular/cdk/dialog';
+import { Component, EventEmitter, Input, Output, ViewContainerRef } from '@angular/core';
+import { filter } from 'rxjs';
+import {
+  OzgcloudDialogCommandResult,
+  isDialogSuccessfullyCompleted,
+} from '../../../../../../ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result';
+import {
+  AbschliessenDialogData,
+  BescheidWizardAbschliessenDialogContainerComponent,
+} from '../abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-abschliessen-button',
+  templateUrl: './bescheid-wizard-abschliessen-button.component.html',
+})
+export class BescheidWizardAbschliessenButtonComponent {
+  @Input() vorgangWithEingangResource: VorgangWithEingangResource;
+
+  @Output() vorgangAbgeschlossen: EventEmitter<void> = new EventEmitter<void>();
+
+  constructor(
+    private readonly ozgclouDialogService: OzgcloudDialogService,
+    readonly viewContainerRef: ViewContainerRef,
+  ) {}
+
+  public onClick(): void {
+    const dialogData: AbschliessenDialogData = {
+      vorgangWithEingangResource: this.vorgangWithEingangResource,
+    };
+
+    const dialogRef: DialogRef<OzgcloudDialogCommandResult> =
+      this.ozgclouDialogService.openInCallingComponentContext(
+        BescheidWizardAbschliessenDialogContainerComponent,
+        this.viewContainerRef,
+        dialogData,
+      );
+
+    this.handleDialogClosed(dialogRef);
+  }
+
+  handleDialogClosed(dialogRef: DialogRef<OzgcloudDialogCommandResult>): void {
+    dialogRef.closed
+      .pipe(filter(isDialogSuccessfullyCompleted))
+      .subscribe(() => this.vorgangAbgeschlossen.emit());
+  }
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..2bdd79f315eb2a6473cd8212ecc895638d9544d4
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.html
@@ -0,0 +1,40 @@
+<div class="relative m-6 max-w-2xl rounded-lg bg-modalBg p-6 shadow-xl" data-test-id="bescheid-ueberspringen-dialog">
+  <button
+    class="absolute right-4 top-4 flex size-12 items-center justify-center rounded-full hover:bg-background-100"
+    (click)="onClose()"
+    data-test-id="close-bescheid-button"
+  >
+    <mat-icon>close</mat-icon>
+  </button>
+
+  <div class="flex flex-col gap-6">
+    <div>
+      <h4 class="text-lg font-medium text-primary">Bescheiderstellung überspringen</h4>
+    </div>
+    <div class="grow">
+      <p class="text-base">
+        Soll die Bescheiderstellung übersprungen und der Vorgang direkt in den Status Abgeschlossen gesetzt werden?
+      </p>
+    </div>
+    <div class="flex gap-4">
+      <ozgcloud-stroked-button-with-spinner
+        (click)="onConfirm()"
+        data-test-id="ueberspringen-abschliessen-button"
+        text="Überspringen und abschließen"
+        type="submit"
+        icon="check"
+        [stateResource]="abschliessen$ | async"
+      >
+      </ozgcloud-stroked-button-with-spinner>
+      <ozgcloud-stroked-button-with-spinner
+        (click)="onClose()"
+        data-test-id="ueberspringen-abbrechen-button"
+        text="Abbrechen"
+        color=""
+        icon="clear"
+        type="submit"
+      >
+      </ozgcloud-stroked-button-with-spinner>
+    </div>
+  </div>
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fa2987b0468830953c4d0a7d86c9d66f3e57e27e
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.spec.ts
@@ -0,0 +1,173 @@
+import { BescheidService } from '@alfa-client/bescheid-shared';
+import { CommandResource } from '@alfa-client/command-shared';
+import { StateResource } from '@alfa-client/tech-shared';
+import {
+  createDialogRefMock,
+  DialogRefMock,
+  getElementComponentFromFixtureByCss,
+  mock,
+  Mock,
+  triggerEvent,
+} from '@alfa-client/test-utils';
+import { OzgcloudStrokedButtonWithSpinnerComponent } from '@alfa-client/ui';
+import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatIcon } from '@angular/material/icon';
+import { MockComponent } from 'ng-mocks';
+import { of } from 'rxjs';
+import { createSuccessfullyDoneCommandStateResource } from '../../../../../../command-shared/test/command';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import { singleColdCompleted } from '../../../../../../tech-shared/test/marbles';
+import { createDialogResult } from '../../../../../../ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result';
+import { createVorgangWithEingangResource } from '../../../../../../vorgang-shared/test/vorgang';
+import {
+  AbschliessenDialogData,
+  BescheidWizardAbschliessenDialogContainerComponent,
+} from './bescheid-wizard-abschliessen-dialog-container.component';
+
+describe('BescheidWizardAbschliessenDialogContainerComponent', () => {
+  let component: BescheidWizardAbschliessenDialogContainerComponent;
+  let fixture: ComponentFixture<BescheidWizardAbschliessenDialogContainerComponent>;
+
+  const closeBescheidButton: string = getDataTestIdOf('close-bescheid-button');
+  const confirmButtonDataTestId: string = getDataTestIdOf('ueberspringen-abschliessen-button');
+  const cancelButtonDataTestId: string = getDataTestIdOf('ueberspringen-abbrechen-button');
+  const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
+  const dialogData: AbschliessenDialogData = { vorgangWithEingangResource };
+
+  let dialogRef: DialogRefMock;
+  let bescheidService: Mock<BescheidService>;
+
+  beforeEach(() => {
+    bescheidService = mock(BescheidService);
+    dialogRef = createDialogRefMock();
+  });
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [
+        BescheidWizardAbschliessenDialogContainerComponent,
+        MockComponent(MatIcon),
+        MockComponent(OzgcloudStrokedButtonWithSpinnerComponent),
+      ],
+      providers: [
+        {
+          provide: DIALOG_DATA,
+          useValue: dialogData,
+        },
+        {
+          provide: DialogRef,
+          useValue: dialogRef,
+        },
+        {
+          provide: BescheidService,
+          useValue: bescheidService,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardAbschliessenDialogContainerComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('component', () => {
+    describe('onClose', () => {
+      it('should close dialog', () => {
+        component.onClose();
+
+        expect(dialogRef.close).toHaveBeenCalled();
+      });
+    });
+
+    describe('onConfirm', () => {
+      it('should call bescheid service', () => {
+        const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource();
+        bescheidService.bescheidErstellungUeberspringen.mockReturnValue(of(commandStateResource));
+
+        component.onConfirm();
+
+        expect(bescheidService.bescheidErstellungUeberspringen).toHaveBeenCalledWith(vorgangWithEingangResource);
+      });
+
+      it('should set abschliessen$', () => {
+        const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource();
+        bescheidService.bescheidErstellungUeberspringen.mockReturnValue(of(commandStateResource));
+
+        component.onConfirm();
+
+        expect(component.abschliessen$).toBeObservable(singleColdCompleted(commandStateResource));
+      });
+
+      it('should close dialog', () => {
+        const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource();
+        bescheidService.bescheidErstellungUeberspringen.mockReturnValue(of(commandStateResource));
+
+        component.onConfirm();
+        component.abschliessen$.subscribe();
+
+        expect(dialogRef.close).toHaveBeenCalledWith(createDialogResult(commandStateResource));
+      });
+    });
+  });
+
+  describe('template', () => {
+    describe('button close', () => {
+      describe('output', () => {
+        it('should call onClose', () => {
+          component.onClose = jest.fn();
+
+          triggerEvent({ fixture, name: 'click', elementSelector: closeBescheidButton });
+
+          expect(component.onClose).toHaveBeenCalled();
+        });
+      });
+    });
+
+    describe('ozgcloud-stroked-button-with-spinner Überspringen und abschließen', () => {
+      function getElementComponent(): OzgcloudStrokedButtonWithSpinnerComponent {
+        return getElementComponentFromFixtureByCss(fixture, confirmButtonDataTestId);
+      }
+
+      describe('input', () => {
+        it('should set stateResource', () => {
+          const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource();
+          component.abschliessen$ = of(commandStateResource);
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().stateResource).toBe(commandStateResource);
+        });
+      });
+
+      describe('output', () => {
+        it('should call onConfirm', () => {
+          component.onConfirm = jest.fn();
+
+          triggerEvent({
+            fixture,
+            name: 'click',
+            elementSelector: confirmButtonDataTestId,
+          });
+
+          expect(component.onConfirm).toHaveBeenCalled();
+        });
+      });
+    });
+
+    describe('ozgcloud-stroked-button-with-spinner Abbrechen', () => {
+      it('should call onClose', () => {
+        component.onClose = jest.fn();
+
+        triggerEvent({ fixture, name: 'click', elementSelector: cancelButtonDataTestId });
+
+        expect(component.onClose).toHaveBeenCalled();
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4a6fa9de521ad52203dd2cbd2bc86a2365146908
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component.ts
@@ -0,0 +1,40 @@
+import { BescheidService } from '@alfa-client/bescheid-shared';
+import { CommandResource, tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared';
+import { StateResource } from '@alfa-client/tech-shared';
+import { createDialogResult } from '@alfa-client/ui';
+import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
+import { Component, Inject } from '@angular/core';
+import { Observable } from 'rxjs';
+
+export interface AbschliessenDialogData {
+  vorgangWithEingangResource: VorgangWithEingangResource;
+}
+
+@Component({
+  selector: 'alfa-bescheid-wizard-abschliessen-dialog-container',
+  templateUrl: './bescheid-wizard-abschliessen-dialog-container.component.html',
+})
+export class BescheidWizardAbschliessenDialogContainerComponent {
+  public abschliessen$: Observable<StateResource<CommandResource>>;
+
+  constructor(
+    @Inject(DIALOG_DATA) private readonly dialogData: AbschliessenDialogData,
+    private readonly dialogRef: DialogRef,
+    private readonly bescheidService: BescheidService,
+  ) {}
+
+  public onClose(): void {
+    this.dialogRef.close();
+  }
+
+  public onConfirm(): void {
+    this.abschliessen$ = this.bescheidService
+      .bescheidErstellungUeberspringen(this.dialogData.vorgangWithEingangResource)
+      .pipe(
+        tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) =>
+          this.dialogRef.close(createDialogResult(commandStateResource)),
+        ),
+      );
+  }
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..3e3e0d9f2ddf27f8d7dec24face746611c03064f
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.html
@@ -0,0 +1,26 @@
+<div class="mt-2 grid h-full grid-cols-[min-content_1fr_1fr] gap-7">
+  <alfa-bescheid-wizard-stepper
+    [activeStep]="bescheidWizardStep.AntragBescheiden"
+    data-test-id="wizard-stepper"
+  ></alfa-bescheid-wizard-stepper>
+  <div>
+    <alfa-bescheid-wizard-step-title label="Antrag bescheiden" data-test-id="wizard-step-title"></alfa-bescheid-wizard-step-title>
+    <alfa-bescheid-wizard-antrag-bescheiden-form
+      [vorgangWithEingangResource]="vorgangWithEingangResource"
+      [bescheidResource]="bescheidResource"
+      [submitStateResource]="submitStateResource"
+      (weiterClickEmitter)="weiterClickEmitter.emit(bescheidWizardStep.DokumenteHochladen)"
+      data-test-id="antrag-bescheiden-form"
+    ></alfa-bescheid-wizard-antrag-bescheiden-form>
+    <alfa-bescheid-wizard-abschliessen-button
+      [vorgangWithEingangResource]="vorgangWithEingangResource"
+      (vorgangAbgeschlossen)="vorgangAbgeschlossen.emit()"
+      data-test-id="wizard-abschliessen-button"
+    ></alfa-bescheid-wizard-abschliessen-button>
+  </div>
+  <alfa-bescheid-wizard-summary data-test-id="wizard-summary">
+    <alfa-bescheid-wizard-antrag-bescheiden-summary
+      data-test-id="antrag-bescheiden-summary"
+    ></alfa-bescheid-wizard-antrag-bescheiden-summary>
+  </alfa-bescheid-wizard-summary>
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..76204aa7e07e108f2b6221be33170b8a754b7c5c
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.spec.ts
@@ -0,0 +1,184 @@
+import { BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { Mock, existsAsHtmlElement, getElementFromFixtureByType, mock, triggerEvent, useFromMock } from '@alfa-client/test-utils';
+import { EventEmitter } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MockComponent } from 'ng-mocks';
+import { createBescheidResource } from '../../../../../../bescheid-shared/src/test/bescheid';
+import { createCommandStateResource } from '../../../../../../command-shared/test/command';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import { createVorgangWithEingangResource } from '../../../../../../vorgang-shared/test/vorgang';
+import { BescheidWizardAbschliessenButtonComponent } from '../abschliessen-button/bescheid-wizard-abschliessen-button.component';
+import { BescheidWizardStepTitleComponent } from '../step-title/bescheid-wizard-step-title.component';
+import { BescheidWizardStepperComponent } from '../stepper/bescheid-wizard-stepper.component';
+import { BescheidWizardSummaryComponent } from '../summary/bescheid-wizard-summary.component';
+import { BescheidWizardAntragBescheidenComponent } from './bescheid-wizard-antrag-bescheiden.component';
+import { BescheidWizardAntragBescheidenFormComponent } from './form/bescheid-wizard-antrag-bescheiden-form.component';
+import { BescheidWizardAntragBescheidenSummaryComponent } from './summary/bescheid-wizard-antrag-bescheiden-summary.component';
+
+describe('BescheidWizardAntragBescheidenComponent', () => {
+  let component: BescheidWizardAntragBescheidenComponent;
+  let fixture: ComponentFixture<BescheidWizardAntragBescheidenComponent>;
+
+  const wizardStepper: string = getDataTestIdOf('wizard-stepper');
+  const wizardStepTitle: string = getDataTestIdOf('wizard-step-title');
+  const antragBescheidenForm: string = getDataTestIdOf('antrag-bescheiden-form');
+  const abschliessenButton: string = getDataTestIdOf('wizard-abschliessen-button');
+  const wizardSummary: string = getDataTestIdOf('wizard-summary');
+  const antragBescheidenSummary: string = getDataTestIdOf('antrag-bescheiden-summary');
+
+  let bescheidService: Mock<BescheidService>;
+
+  beforeEach(() => {
+    bescheidService = mock(BescheidService);
+  });
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [
+        BescheidWizardAntragBescheidenComponent,
+        MockComponent(BescheidWizardStepTitleComponent),
+        MockComponent(BescheidWizardAntragBescheidenFormComponent),
+        MockComponent(BescheidWizardSummaryComponent),
+        MockComponent(BescheidWizardAntragBescheidenSummaryComponent),
+        MockComponent(BescheidWizardAbschliessenButtonComponent),
+        MockComponent(BescheidWizardStepperComponent),
+      ],
+      providers: [
+        {
+          provide: BescheidService,
+          useValue: bescheidService,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardAntragBescheidenComponent);
+    component = fixture.componentInstance;
+    component.weiterClickEmitter = useFromMock(mock(EventEmitter<BescheidWizardStep>));
+    component.vorgangAbgeschlossen = useFromMock(mock(EventEmitter<void>));
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('alfa-bescheid-wizard-stepper', () => {
+      function getElementComponent(): BescheidWizardStepperComponent {
+        return getElementFromFixtureByType(fixture, BescheidWizardStepperComponent);
+      }
+
+      it('should exists', () => {
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, wizardStepper);
+      });
+
+      describe('input', () => {
+        it('should set activeStep', () => {
+          fixture.detectChanges();
+
+          expect(getElementComponent().activeStep).toBe(BescheidWizardStep.AntragBescheiden);
+        });
+      });
+    });
+
+    describe('alfa-bescheid-wizard-step-title', () => {
+      it('should show', () => {
+        existsAsHtmlElement(fixture, wizardStepTitle);
+      });
+    });
+
+    describe('alfa-bescheid-wizard-summary', () => {
+      it('should show', () => {
+        existsAsHtmlElement(fixture, wizardSummary);
+      });
+    });
+
+    describe('alfa-bescheid-wizard-antrag-bescheiden-summary', () => {
+      it('should show', () => {
+        existsAsHtmlElement(fixture, antragBescheidenSummary);
+      });
+    });
+
+    describe('alfa-bescheid-wizard-abschliessen-button', () => {
+      function getElementComponent(): BescheidWizardAbschliessenButtonComponent {
+        return getElementFromFixtureByType(fixture, BescheidWizardAbschliessenButtonComponent);
+      }
+
+      it('should show', () => {
+        existsAsHtmlElement(fixture, abschliessenButton);
+      });
+
+      describe('input', () => {
+        it('should set vorgangWithEingangResource', () => {
+          component.vorgangWithEingangResource = createVorgangWithEingangResource();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().vorgangWithEingangResource).toBe(component.vorgangWithEingangResource);
+        });
+      });
+
+      describe('output', () => {
+        it('should call onVorgangAbgeschlossen', () => {
+          triggerEvent({
+            fixture,
+            name: 'vorgangAbgeschlossen',
+            elementSelector: abschliessenButton,
+          });
+
+          expect(component.vorgangAbgeschlossen.emit).toHaveBeenCalled();
+        });
+      });
+    });
+
+    describe('alfa-bescheid-wizard-antrag-bescheiden-form', () => {
+      function getElementComponent(): BescheidWizardAntragBescheidenFormComponent {
+        return getElementFromFixtureByType(fixture, BescheidWizardAntragBescheidenFormComponent);
+      }
+
+      it('should show', () => {
+        existsAsHtmlElement(fixture, antragBescheidenForm);
+      });
+
+      describe('input', () => {
+        it('should set vorgangWithEingangResource', () => {
+          component.vorgangWithEingangResource = createVorgangWithEingangResource();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().vorgangWithEingangResource).toBe(component.vorgangWithEingangResource);
+        });
+
+        it('should set bescheidResource', () => {
+          component.bescheidResource = createBescheidResource();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().bescheidResource).toBe(component.bescheidResource);
+        });
+
+        it('should set submitStateResource', () => {
+          component.submitStateResource = createCommandStateResource();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().submitStateResource).toBe(component.submitStateResource);
+        });
+      });
+
+      describe('output', () => {
+        it('should emit weiterClickEmitter', () => {
+          triggerEvent({
+            fixture,
+            name: 'weiterClickEmitter',
+            elementSelector: antragBescheidenForm,
+          });
+
+          expect(component.weiterClickEmitter.emit).toHaveBeenCalledWith(BescheidWizardStep.DokumenteHochladen);
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ad21a4d0358b3a81919618ad43a2765328c425d1
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component.ts
@@ -0,0 +1,20 @@
+import { BescheidResource, BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { StateResource } from '@alfa-client/tech-shared';
+import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-antrag-bescheiden',
+  templateUrl: './bescheid-wizard-antrag-bescheiden.component.html',
+})
+export class BescheidWizardAntragBescheidenComponent {
+  @Input() vorgangWithEingangResource: VorgangWithEingangResource;
+  @Input() bescheidResource: BescheidResource;
+  @Input() submitStateResource: StateResource<Resource>;
+
+  @Output() weiterClickEmitter: EventEmitter<BescheidWizardStep> = new EventEmitter<BescheidWizardStep>();
+  @Output() vorgangAbgeschlossen: EventEmitter<void> = new EventEmitter<void>();
+
+  public readonly bescheidWizardStep = BescheidWizardStep;
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..1dc1beea0753e8e1ccdd0eff9e7a2c20438c301e
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.html
@@ -0,0 +1,38 @@
+<div [formGroup]="formService.form" role="radiogroup" aria-label="Bescheidstatus">
+  <div class="my-10 flex max-w-2xl gap-8">
+    <ods-radio-button-card
+      label="bewilligt"
+      [name]="formServiceClass.FIELD_BEWILLIGT"
+      value="true"
+      data-test-id="button-bewilligt"
+      variant="bescheid_bewilligt"
+      ><ods-stamp-icon size="large"></ods-stamp-icon>
+    </ods-radio-button-card>
+    <ods-radio-button-card
+      label="abgelehnt"
+      [name]="formServiceClass.FIELD_BEWILLIGT"
+      value="false"
+      data-test-id="button-abgelehnt"
+      variant="bescheid_abgelehnt"
+      ><ods-close-icon size="large" class="fill-abgelehnt"></ods-close-icon>
+    </ods-radio-button-card>
+  </div>
+  <div class="flex w-full">
+    <ozgcloud-date-editor
+      [formControlName]="formServiceClass.FIELD_BESCHIEDEN_AM"
+      label="am"
+      aria-label="Bescheiddatum"
+      [required]="true"
+    >
+    </ozgcloud-date-editor>
+  </div>
+</div>
+<alfa-bescheid-wizard-weiter-button
+  *ngIf="
+    (vorgangWithEingangResource | hasLink: vorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT) ||
+    (bescheidResource | hasLink: bescheidLinkRel.UPDATE)
+  "
+  [submitStateResource]="submitStateResource"
+  (clickEmitter)="weiterClickEmitter.emit()"
+  data-test-id="weiter-button"
+></alfa-bescheid-wizard-weiter-button>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d81a9ee233fd8ce80910fe10ffb2b625dc3f09c4
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.spec.ts
@@ -0,0 +1,112 @@
+import { BescheidLinkRel, BescheidService } from '@alfa-client/bescheid-shared';
+import { HasLinkPipe } from '@alfa-client/tech-shared';
+import { existsAsHtmlElement, mock, notExistsAsHtmlElement, triggerEvent, useFromMock } from '@alfa-client/test-utils';
+import { DateEditorComponent } from '@alfa-client/ui';
+import { VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared';
+import { EventEmitter } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms';
+import { CloseIconComponent, RadioButtonCardComponent, StampIconComponent } from '@ods/system';
+import { MockComponent } from 'ng-mocks';
+import { createBescheidResource } from '../../../../../../../bescheid-shared/src/test/bescheid';
+import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test';
+import { createVorgangWithEingangResource } from '../../../../../../../vorgang-shared/test/vorgang';
+import { BescheidFormService } from '../../../bescheid.formservice';
+import { BescheidWizardWeiterButtonComponent } from '../../weiter-button/bescheid-wizard-weiter-button.component';
+import { BescheidWizardAntragBescheidenFormComponent } from './bescheid-wizard-antrag-bescheiden-form.component';
+
+describe('BescheidWizardAntragBescheidenFormComponent', () => {
+  let component: BescheidWizardAntragBescheidenFormComponent;
+  let fixture: ComponentFixture<BescheidWizardAntragBescheidenFormComponent>;
+
+  const weiterButton: string = getDataTestIdOf('weiter-button');
+
+  let formService: BescheidFormService;
+
+  beforeEach(async () => {
+    formService = new BescheidFormService(new UntypedFormBuilder(), useFromMock(mock(BescheidService)));
+
+    await TestBed.configureTestingModule({
+      declarations: [
+        BescheidWizardAntragBescheidenFormComponent,
+        HasLinkPipe,
+        MockComponent(BescheidWizardWeiterButtonComponent),
+        MockComponent(RadioButtonCardComponent),
+        MockComponent(StampIconComponent),
+        MockComponent(CloseIconComponent),
+        MockComponent(DateEditorComponent),
+      ],
+      providers: [
+        {
+          provide: BescheidFormService,
+          useValue: formService,
+        },
+      ],
+      imports: [ReactiveFormsModule],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardAntragBescheidenFormComponent);
+    component = fixture.componentInstance;
+    component.weiterClickEmitter = useFromMock(mock(EventEmitter<void>));
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('alfa-bescheid-wizard-weiter-button', () => {
+      it('should exists if bescheid update link exists', () => {
+        component.bescheidResource = createBescheidResource([BescheidLinkRel.UPDATE]);
+
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, weiterButton);
+      });
+
+      it('should exists if create link exists', () => {
+        component.vorgangWithEingangResource = createVorgangWithEingangResource([
+          VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
+        ]);
+
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, weiterButton);
+      });
+
+      it('should not exists if update and create links missing', () => {
+        component.vorgangWithEingangResource = createVorgangWithEingangResource();
+        component.bescheidResource = createBescheidResource();
+
+        fixture.detectChanges();
+
+        notExistsAsHtmlElement(fixture, weiterButton);
+      });
+
+      it('should not exists if update link missing', () => {
+        component.bescheidResource = createBescheidResource();
+
+        fixture.detectChanges();
+
+        notExistsAsHtmlElement(fixture, weiterButton);
+      });
+
+      describe('output', () => {
+        it('should emit weiterClickEmitter', () => {
+          component.bescheidResource = createBescheidResource([BescheidLinkRel.UPDATE]);
+
+          fixture.detectChanges();
+
+          triggerEvent({
+            fixture,
+            name: 'clickEmitter',
+            elementSelector: weiterButton,
+          });
+
+          expect(component.weiterClickEmitter.emit).toHaveBeenCalled();
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b4b99c96e31bbb2702c7c0982de44ed7abc7bdbb
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component.ts
@@ -0,0 +1,24 @@
+import { BescheidLinkRel, BescheidResource } from '@alfa-client/bescheid-shared';
+import { StateResource } from '@alfa-client/tech-shared';
+import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+import { BescheidFormService } from '../../../bescheid.formservice';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-antrag-bescheiden-form',
+  templateUrl: './bescheid-wizard-antrag-bescheiden-form.component.html',
+})
+export class BescheidWizardAntragBescheidenFormComponent {
+  @Input() vorgangWithEingangResource: VorgangWithEingangResource;
+  @Input() bescheidResource: BescheidResource;
+  @Input() submitStateResource: StateResource<Resource>;
+
+  @Output() weiterClickEmitter = new EventEmitter<void>();
+
+  public readonly vorgangWithEingangLinkRel = VorgangWithEingangLinkRel;
+  public readonly bescheidLinkRel = BescheidLinkRel;
+  public readonly formServiceClass = BescheidFormService;
+
+  constructor(public readonly formService: BescheidFormService) {}
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..995ee6afa5bd8ee9fdb5f5309264dc6ca853c769
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.html
@@ -0,0 +1,7 @@
+<ods-bescheid-status-text
+  *ngIf="formService.getBescheidFormValueChanges() | async as bescheid"
+  [bewilligt]="bescheid.bewilligt"
+  [dateText]="bescheid.beschiedenAm | date: 'dd.MM.yyyy'"
+  [hasBescheidDraft]="false"
+  data-test-id="bescheid-status-text"
+></ods-bescheid-status-text>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..588b4227c7a9ab76f83f438390a3b4ff717cd4e2
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.spec.ts
@@ -0,0 +1,97 @@
+import { Bescheid } from '@alfa-client/bescheid-shared';
+import { existsAsHtmlElement, getElementFromFixtureByType, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BescheidStatusTextComponent } from '@ods/system';
+import { MockComponent } from 'ng-mocks';
+import { EMPTY, of } from 'rxjs';
+import { createBescheid } from '../../../../../../../bescheid-shared/src/test/bescheid';
+import { getDataTestIdOf } from '../../../../../../../tech-shared/test/data-test';
+import { BescheidFormService } from '../../../bescheid.formservice';
+import { BescheidWizardAntragBescheidenSummaryComponent } from './bescheid-wizard-antrag-bescheiden-summary.component';
+
+describe('BescheidWizardAntragBescheidenSummaryComponent', () => {
+  let component: BescheidWizardAntragBescheidenSummaryComponent;
+  let fixture: ComponentFixture<BescheidWizardAntragBescheidenSummaryComponent>;
+
+  const bescheidStatusText: string = getDataTestIdOf('bescheid-status-text');
+
+  let formService: Mock<BescheidFormService>;
+
+  beforeEach(() => {
+    formService = mock(BescheidFormService);
+  });
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardAntragBescheidenSummaryComponent, MockComponent(BescheidStatusTextComponent)],
+      providers: [{ provide: BescheidFormService, useValue: formService }],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardAntragBescheidenSummaryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('ods-bescheid-status-text', () => {
+      function getElementComponent(): BescheidStatusTextComponent {
+        return getElementFromFixtureByType(fixture, BescheidStatusTextComponent);
+      }
+
+      it('should subscribe to bescheid value form changes', () => {
+        fixture.detectChanges();
+
+        expect(formService.getBescheidFormValueChanges).toHaveBeenCalled();
+      });
+
+      it('should NOT show', () => {
+        formService.getBescheidFormValueChanges.mockReturnValue(EMPTY);
+
+        fixture.detectChanges();
+
+        notExistsAsHtmlElement(fixture, bescheidStatusText);
+      });
+
+      it('should show', () => {
+        formService.getBescheidFormValueChanges.mockReturnValue(of(createBescheid()));
+
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, bescheidStatusText);
+      });
+
+      describe('input', () => {
+        it('should set bewilligt', () => {
+          const bescheid: Bescheid = createBescheid();
+          formService.getBescheidFormValueChanges.mockReturnValue(of(bescheid));
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().bewilligt).toBe(bescheid.bewilligt);
+        });
+
+        it('should set dateText', () => {
+          const bescheid: Bescheid = { ...createBescheid(), beschiedenAm: '2024-01-01' };
+          formService.getBescheidFormValueChanges.mockReturnValue(of(bescheid));
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().dateText).toBe('01.01.2024');
+        });
+
+        it('should set hasBescheidDraft', () => {
+          const bescheid: Bescheid = createBescheid();
+          formService.getBescheidFormValueChanges.mockReturnValue(of(bescheid));
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().hasBescheidDraft).toBeFalsy();
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dde93bf38267d618753bf41429fc0fceff973ad0
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+import { BescheidFormService } from '../../../bescheid.formservice';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-antrag-bescheiden-summary',
+  templateUrl: './bescheid-wizard-antrag-bescheiden-summary.component.html',
+})
+export class BescheidWizardAntragBescheidenSummaryComponent {
+  constructor(public readonly formService: BescheidFormService) {}
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..5f1b875910deb42d189e8077528fb9a6329826a7
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.html
@@ -0,0 +1,24 @@
+<ozgcloud-spinner
+  *ngIf="(vorgangWithEingangResource | hasLink: vorgangWithEingangLinkRel.BESCHEID_DRAFT) && !bescheidStateResource.resource"
+  [stateResource]="bescheidStateResource"
+  class="absolute flex size-full items-center justify-center"
+  data-test-id="bescheid-loading-spinner"
+></ozgcloud-spinner>
+
+<form [formGroup]="formService.form" class="h-full">
+  <div class="grid h-full">
+    <alfa-bescheid-wizard-antrag-bescheiden
+      *ngIf="activeStep === bescheidWizardStep.AntragBescheiden"
+      [vorgangWithEingangResource]="vorgangWithEingangResource"
+      [bescheidResource]="bescheidStateResource.resource"
+      [submitStateResource]="submitStateResource"
+      (weiterClickEmitter)="weiterClickEmitter.emit($event)"
+      (vorgangAbgeschlossen)="vorgangAbgeschlossen.emit()"
+      data-test-id="antrag-bescheiden-step"
+    ></alfa-bescheid-wizard-antrag-bescheiden>
+    <alfa-bescheid-wizard-dokumente-hochladen
+      *ngIf="activeStep === bescheidWizardStep.DokumenteHochladen"
+      data-test-id="dokumente-hochladen-step"
+    ></alfa-bescheid-wizard-dokumente-hochladen>
+  </div>
+</form>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7e66bad67b2d553ba8f221bd69e480b1ae3b79de
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.spec.ts
@@ -0,0 +1,252 @@
+import { BescheidResource, BescheidService, BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { HasLinkPipe, StateResource, createEmptyStateResource } from '@alfa-client/tech-shared';
+import {
+  Mock,
+  existsAsHtmlElement,
+  getElementFromFixtureByType,
+  mock,
+  notExistsAsHtmlElement,
+  triggerEvent,
+  useFromMock,
+} from '@alfa-client/test-utils';
+import { SpinnerComponent } from '@alfa-client/ui';
+import { VorgangWithEingangLinkRel } from '@alfa-client/vorgang-shared';
+import { EventEmitter } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms';
+import { MockComponent } from 'ng-mocks';
+import { createBescheidStateResource } from '../../../../../bescheid-shared/src/test/bescheid';
+import { createSuccessfullyDoneCommandStateResource } from '../../../../../command-shared/test/command';
+import { getDataTestIdOf } from '../../../../../tech-shared/test/data-test';
+import { createVorgangWithEingangResource } from '../../../../../vorgang-shared/test/vorgang';
+import { BescheidFormService } from '../bescheid.formservice';
+import { BescheidWizardAntragBescheidenComponent } from './antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component';
+import { BescheidWizardComponent } from './bescheid-wizard.component';
+import { BescheidWizardDokumenteHochladenComponent } from './dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component';
+import { BescheidWizardStepperComponent } from './stepper/bescheid-wizard-stepper.component';
+
+describe('BescheidWizardComponent', () => {
+  let component: BescheidWizardComponent;
+  let fixture: ComponentFixture<BescheidWizardComponent>;
+
+  const bescheidLoadingSpinner: string = getDataTestIdOf('bescheid-loading-spinner');
+  const antragBescheidenStep: string = getDataTestIdOf('antrag-bescheiden-step');
+  const dokumenteHochladenStep: string = getDataTestIdOf('dokumente-hochladen-step');
+
+  let bescheidService: Mock<BescheidService>;
+  let formService: BescheidFormService;
+
+  beforeEach(() => {
+    bescheidService = mock(BescheidService);
+    formService = new BescheidFormService(new UntypedFormBuilder(), useFromMock(bescheidService));
+  });
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [
+        BescheidWizardComponent,
+        MockComponent(BescheidWizardStepperComponent),
+        MockComponent(BescheidWizardAntragBescheidenComponent),
+        MockComponent(BescheidWizardDokumenteHochladenComponent),
+        MockComponent(SpinnerComponent),
+        HasLinkPipe,
+      ],
+      providers: [
+        {
+          provide: BescheidFormService,
+          useValue: formService,
+        },
+      ],
+      imports: [ReactiveFormsModule],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardComponent);
+    component = fixture.componentInstance;
+    component.weiterClickEmitter = useFromMock(mock(EventEmitter<BescheidWizardStep>));
+    component.vorgangAbgeschlossen = useFromMock(mock(EventEmitter<void>));
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('component', () => {
+    describe('set bescheidDraftStateResource', () => {
+      it('should patch form values', () => {
+        formService.patchValues = jest.fn();
+
+        component.bescheidStateResource = createBescheidStateResource();
+
+        expect(formService.patchValues).toHaveBeenCalledWith(component.bescheidStateResource.resource);
+      });
+
+      it('should NOT patch form values', () => {
+        formService.patchValues = jest.fn();
+
+        component.bescheidStateResource = createEmptyStateResource();
+
+        expect(formService.patchValues).not.toHaveBeenCalled();
+      });
+
+      it('should set bescheid state resource', () => {
+        component.bescheidStateResource = createBescheidStateResource();
+
+        expect(component.bescheidStateResource).toEqual(component.bescheidStateResource);
+      });
+    });
+  });
+
+  describe('template', () => {
+    beforeEach(() => {
+      component.bescheidStateResource = createBescheidStateResource();
+    });
+
+    describe('ozgcloud-spinner', () => {
+      it('should exists', () => {
+        component.vorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT]);
+        component.bescheidStateResource = createEmptyStateResource();
+
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, bescheidLoadingSpinner);
+      });
+
+      it('should NOT exists if bescheid does not exists', () => {
+        component.vorgangWithEingangResource = createVorgangWithEingangResource();
+        component.bescheidStateResource = createEmptyStateResource();
+
+        fixture.detectChanges();
+
+        notExistsAsHtmlElement(fixture, bescheidLoadingSpinner);
+      });
+
+      it('should NOT exists if bescheid initially loaded', () => {
+        component.vorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT]);
+        component.bescheidStateResource = createBescheidStateResource();
+
+        fixture.detectChanges();
+
+        notExistsAsHtmlElement(fixture, bescheidLoadingSpinner);
+      });
+
+      describe('input', () => {
+        it('should set stateResource', () => {
+          component.vorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT]);
+          component.bescheidStateResource = createEmptyStateResource();
+
+          fixture.detectChanges();
+
+          expect(getElementFromFixtureByType(fixture, SpinnerComponent).stateResource).toEqual(component.bescheidStateResource);
+        });
+      });
+    });
+
+    describe('alfa-bescheid-wizard-antrag-bescheiden', () => {
+      function getElementComponent(): BescheidWizardAntragBescheidenComponent {
+        return getElementFromFixtureByType(fixture, BescheidWizardAntragBescheidenComponent);
+      }
+
+      it('should show', () => {
+        givenActiveStep(1);
+        givenLoadedBescheidStateResrouce();
+
+        existsAsHtmlElement(fixture, antragBescheidenStep);
+      });
+
+      it.each([2, 3])('should NOT show in step %d', (step: number) => {
+        givenActiveStep(step);
+        givenLoadedBescheidStateResrouce();
+
+        notExistsAsHtmlElement(fixture, antragBescheidenStep);
+      });
+
+      describe('input', () => {
+        it('should set vorgangWithEingangResource', () => {
+          givenActiveStep(1);
+          givenLoadedBescheidStateResrouce();
+          component.vorgangWithEingangResource = createVorgangWithEingangResource();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().vorgangWithEingangResource).toBe(component.vorgangWithEingangResource);
+        });
+
+        it('should set bescheidResource', () => {
+          givenActiveStep(1);
+          givenLoadedBescheidStateResrouce();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().bescheidResource).toEqual(component.bescheidStateResource.resource);
+        });
+
+        it('should set submitStateResource', () => {
+          givenActiveStep(1);
+          givenLoadedBescheidStateResrouce();
+          component.submitStateResource = createSuccessfullyDoneCommandStateResource();
+
+          fixture.detectChanges();
+
+          expect(getElementComponent().submitStateResource).toEqual(component.submitStateResource);
+        });
+      });
+
+      describe('output', () => {
+        beforeEach(() => {
+          givenActiveStep(1);
+          givenLoadedBescheidStateResrouce();
+        });
+
+        it('should emit weiterClickEmitter', () => {
+          triggerEvent({
+            fixture,
+            name: 'weiterClickEmitter',
+            elementSelector: antragBescheidenStep,
+            data: BescheidWizardStep.DokumenteHochladen,
+          });
+
+          expect(component.weiterClickEmitter.emit).toHaveBeenCalledWith(BescheidWizardStep.DokumenteHochladen);
+        });
+
+        it('should emit vorgangAbgeschlossen', () => {
+          triggerEvent({
+            fixture,
+            name: 'vorgangAbgeschlossen',
+            elementSelector: antragBescheidenStep,
+          });
+
+          expect(component.vorgangAbgeschlossen.emit).toHaveBeenCalled();
+        });
+      });
+    });
+
+    describe('alfa-bescheid-wizard-dokumente-hochladen', () => {
+      it('should show', () => {
+        givenActiveStep(2);
+        givenLoadedBescheidStateResrouce();
+
+        existsAsHtmlElement(fixture, dokumenteHochladenStep);
+      });
+
+      it.each([1, 3])('should NOT show in step %d', (step: number) => {
+        givenActiveStep(step);
+        givenLoadedBescheidStateResrouce();
+
+        notExistsAsHtmlElement(fixture, dokumenteHochladenStep);
+      });
+    });
+  });
+
+  function givenActiveStep(step: number): void {
+    component.activeStep = step;
+    fixture.detectChanges();
+  }
+
+  function givenLoadedBescheidStateResrouce(): StateResource<BescheidResource> {
+    const resource: StateResource<BescheidResource> = createBescheidStateResource();
+    component.bescheidStateResource = resource;
+    fixture.detectChanges();
+    return resource;
+  }
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6b8a55df5b58c279ccb5c8c7523b71e27f14777d
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component.ts
@@ -0,0 +1,38 @@
+import { BescheidResource, BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { StateResource, isLoaded } from '@alfa-client/tech-shared';
+import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+import { BescheidFormService } from '../bescheid.formservice';
+
+@Component({
+  selector: 'alfa-bescheid-wizard',
+  templateUrl: './bescheid-wizard.component.html',
+})
+export class BescheidWizardComponent {
+  @Input() vorgangWithEingangResource: VorgangWithEingangResource;
+
+  @Input() set bescheidStateResource(value: StateResource<BescheidResource>) {
+    if (isLoaded(value)) {
+      this.formService.patchValues(value.resource);
+    }
+    this._bescheidStateResource = value;
+  }
+
+  get bescheidStateResource(): StateResource<BescheidResource> {
+    return this._bescheidStateResource;
+  }
+
+  @Input() activeStep: number;
+  @Input() submitStateResource: StateResource<Resource>;
+
+  @Output() weiterClickEmitter: EventEmitter<BescheidWizardStep> = new EventEmitter<BescheidWizardStep>();
+  @Output() vorgangAbgeschlossen: EventEmitter<void> = new EventEmitter<void>();
+
+  private _bescheidStateResource: StateResource<BescheidResource>;
+
+  public readonly vorgangWithEingangLinkRel = VorgangWithEingangLinkRel;
+  public readonly bescheidWizardStep = BescheidWizardStep;
+
+  constructor(public readonly formService: BescheidFormService) {}
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..7cf2668837a7aa60195d8084d449b58bc2dca71e
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.html
@@ -0,0 +1,36 @@
+<div
+  class="relative m-6 max-w-2xl rounded-lg bg-modalBg p-6 shadow-xl"
+  data-test-id="bescheid-close-dialog"
+>
+  <div class="flex flex-col gap-6">
+    <div>
+      <h4 class="text-lg font-medium text-primary">Bescheiderstellung abbrechen</h4>
+    </div>
+    <div class="grow">
+      <p class="text-base">
+        Soll der Bescheid-Entwurf zur späteren Bearbeitung gespeichert oder verworfen werden?
+      </p>
+    </div>
+    <div class="flex gap-4">
+      <ozgcloud-stroked-button-with-spinner
+        [stateResource]="saveStateResource$ | async"
+        (clickEmitter)="save()"
+        data-test-id="bescheiderstellung-abbrechen-entwurf-speichern"
+        text="Entwurf speichern"
+        type="submit"
+        icon="check"
+      >
+      </ozgcloud-stroked-button-with-spinner>
+      <ozgcloud-stroked-button-with-spinner
+        [stateResource]="deleteStateResource$ | async"
+        (clickEmitter)="cancel()"
+        data-test-id="bescheiderstellung-abbrechen-entwurf-verwerfen"
+        text="Verwerfen"
+        color=""
+        icon="clear"
+        type="submit"
+      >
+      </ozgcloud-stroked-button-with-spinner>
+    </div>
+  </div>
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df7293c3aaf58a881b74c8db3cd173eea81b2cb3
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.spec.ts
@@ -0,0 +1,258 @@
+import { BescheidService } from '@alfa-client/bescheid-shared';
+import { CommandResource } from '@alfa-client/command-shared';
+import { StateResource, createErrorStateResource } from '@alfa-client/tech-shared';
+import {
+  DialogRefMock,
+  Mock,
+  createDialogRefMock,
+  existsAsHtmlElement,
+  getElementComponentFromFixtureByCss,
+  mock,
+  triggerEvent,
+} from '@alfa-client/test-utils';
+import { OzgcloudStrokedButtonWithSpinnerComponent } from '@alfa-client/ui';
+import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MockComponent } from 'ng-mocks';
+import { EMPTY, of } from 'rxjs';
+import { createBescheidResource } from '../../../../../../bescheid-shared/src/test/bescheid';
+import {
+  createCommandStateResource,
+  createSuccessfullyDoneCommandStateResource,
+} from '../../../../../../command-shared/test/command';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import { createApiError } from '../../../../../../tech-shared/test/error';
+import { singleColdCompleted } from '../../../../../../tech-shared/test/marbles';
+import { BescheidFormService } from '../../bescheid.formservice';
+import {
+  BescheidWizardCancelDialogContainerComponent,
+  CancelWizardDialogData,
+} from './bescheid-wizard-cancel-dialog-container.component';
+
+describe('BescheidWizardCancelDialogContainerComponent', () => {
+  let component: BescheidWizardCancelDialogContainerComponent;
+  let fixture: ComponentFixture<BescheidWizardCancelDialogContainerComponent>;
+
+  const speichernButton: string = getDataTestIdOf('bescheiderstellung-abbrechen-entwurf-speichern');
+  const verwerfenButton: string = getDataTestIdOf('bescheiderstellung-abbrechen-entwurf-verwerfen');
+
+  const dialogData: CancelWizardDialogData = {
+    bescheidResource: createBescheidResource(),
+  };
+
+  let formService: Mock<BescheidFormService>;
+  let bescheidService: Mock<BescheidService>;
+  let dialogRef: DialogRefMock;
+
+  beforeEach(() => {
+    formService = { ...mock(BescheidFormService), submit: jest.fn().mockReturnValue(EMPTY) };
+    bescheidService = { ...mock(BescheidService), bescheidVerwerfen: jest.fn().mockReturnValue(EMPTY) };
+    dialogRef = createDialogRefMock();
+  });
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardCancelDialogContainerComponent, MockComponent(OzgcloudStrokedButtonWithSpinnerComponent)],
+      providers: [
+        {
+          provide: BescheidService,
+          useValue: bescheidService,
+        },
+        {
+          provide: BescheidFormService,
+          useValue: formService,
+        },
+        {
+          provide: DIALOG_DATA,
+          useValue: dialogData,
+        },
+        {
+          provide: DialogRef,
+          useValue: dialogRef,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardCancelDialogContainerComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('component', () => {
+    describe('save', () => {
+      beforeEach(() => {
+        component.closeDialogWithWizard = jest.fn();
+      });
+
+      it('should submit form', () => {
+        component.save();
+
+        expect(formService.submit).toHaveBeenCalled();
+      });
+
+      it('should emit save command state resource', () => {
+        const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
+        formService.submit = jest.fn().mockReturnValue(of(commandStateResource));
+
+        component.save();
+
+        expect(component.saveStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+      });
+
+      it('should handle successfully saved bescheid', () => {
+        const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource();
+        formService.submit = jest.fn().mockReturnValue(of(commandStateResource));
+
+        component.save();
+        component.saveStateResource$.subscribe();
+
+        expect(component.closeDialogWithWizard).toHaveBeenCalled();
+      });
+
+      it('should NOT handle successfully saved bescheid', () => {
+        const commandStateResource: StateResource<CommandResource> = createErrorStateResource(createApiError());
+        formService.submit = jest.fn().mockReturnValue(of(commandStateResource));
+
+        component.save();
+        component.saveStateResource$.subscribe();
+
+        expect(component.closeDialogWithWizard).not.toHaveBeenCalled();
+      });
+    });
+
+    describe('cancel', () => {
+      beforeEach(() => {
+        component.closeDialogWithWizard = jest.fn();
+      });
+
+      it('should delete bescheid', () => {
+        component.cancel();
+
+        expect(bescheidService.bescheidVerwerfen).toHaveBeenCalled();
+      });
+
+      it('should NOT delete bescheid', () => {
+        component.bescheidResource = null;
+
+        component.cancel();
+
+        expect(bescheidService.bescheidVerwerfen).not.toHaveBeenCalled();
+      });
+
+      it('should emit delete command state resource', () => {
+        const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
+        bescheidService.bescheidVerwerfen = jest.fn().mockReturnValue(of(commandStateResource));
+
+        component.cancel();
+
+        expect(component.deleteStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+      });
+
+      it('should close dialog on success', () => {
+        const commandStateResource: StateResource<CommandResource> = createSuccessfullyDoneCommandStateResource();
+        bescheidService.bescheidVerwerfen = jest.fn().mockReturnValue(of(commandStateResource));
+
+        component.cancel();
+        component.deleteStateResource$.subscribe();
+
+        expect(component.closeDialogWithWizard).toHaveBeenCalled();
+      });
+
+      it('should NOT close dialog on error', () => {
+        const commandStateResource: StateResource<CommandResource> = createErrorStateResource(createApiError());
+        bescheidService.bescheidVerwerfen = jest.fn().mockReturnValue(of(commandStateResource));
+
+        component.cancel();
+        component.deleteStateResource$.subscribe();
+
+        expect(component.closeDialogWithWizard).not.toHaveBeenCalled();
+      });
+
+      it('should close dialog with cancel result on non existing bescheid', () => {
+        component.bescheidResource = null;
+
+        component.cancel();
+
+        expect(component.closeDialogWithWizard).toHaveBeenCalled();
+      });
+    });
+
+    describe('closeDialogWithWizard', () => {
+      it('should close', () => {
+        component.closeDialogWithWizard();
+
+        expect(dialogRef.close).toHaveBeenCalledWith({ closeWizard: true });
+      });
+    });
+  });
+
+  describe('template', () => {
+    describe('ozgcloud-stroked-button-with-spinner Entwurf speichern', () => {
+      it('should show', () => {
+        existsAsHtmlElement(fixture, speichernButton);
+      });
+
+      describe('input', () => {
+        it('should set stateResource', () => {
+          const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
+          component.saveStateResource$ = of(commandStateResource);
+
+          const elementComponent: OzgcloudStrokedButtonWithSpinnerComponent = getElementComponentFromFixtureByCss(
+            fixture,
+            speichernButton,
+          );
+
+          fixture.detectChanges();
+
+          expect(elementComponent.stateResource).toBe(commandStateResource);
+        });
+      });
+
+      describe('output', () => {
+        it('should call save', () => {
+          component.save = jest.fn();
+
+          triggerEvent({ fixture, name: 'clickEmitter', elementSelector: speichernButton });
+
+          expect(component.save).toHaveBeenCalled();
+        });
+      });
+    });
+
+    describe('ozgcloud-stroked-button-with-spinner Verwerfen', () => {
+      it('should show', () => {
+        existsAsHtmlElement(fixture, verwerfenButton);
+      });
+
+      describe('input', () => {
+        it('should set stateResource', () => {
+          const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
+          component.deleteStateResource$ = of(commandStateResource);
+
+          const elementComponent: OzgcloudStrokedButtonWithSpinnerComponent = getElementComponentFromFixtureByCss(
+            fixture,
+            verwerfenButton,
+          );
+
+          fixture.detectChanges();
+
+          expect(elementComponent.stateResource).toBe(commandStateResource);
+        });
+      });
+
+      describe('output', () => {
+        it('should call delete', () => {
+          component.cancel = jest.fn();
+
+          triggerEvent({ fixture, name: 'clickEmitter', elementSelector: verwerfenButton });
+
+          expect(component.cancel).toHaveBeenCalled();
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..beb6c19e288f404d7f491398f10107a61e0cdf97
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component.ts
@@ -0,0 +1,53 @@
+import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared';
+import { tapOnCommandSuccessfullyDone } from '@alfa-client/command-shared';
+import { StateResource, isNotNil } from '@alfa-client/tech-shared';
+import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
+import { Component, Inject } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+import { Observable } from 'rxjs';
+import { BescheidFormService } from '../../bescheid.formservice';
+
+export interface CancelWizardDialogData {
+  bescheidResource: BescheidResource;
+}
+
+export interface CancelWizardDialogResult {
+  closeWizard: boolean;
+}
+
+@Component({
+  templateUrl: './bescheid-wizard-cancel-dialog-container.component.html',
+})
+export class BescheidWizardCancelDialogContainerComponent {
+  public saveStateResource$: Observable<StateResource<Resource>>;
+  public deleteStateResource$: Observable<StateResource<Resource>>;
+
+  bescheidResource: BescheidResource;
+
+  constructor(
+    @Inject(DIALOG_DATA) readonly dialogData: CancelWizardDialogData,
+    public dialogRef: DialogRef<CancelWizardDialogResult>,
+    private readonly bescheidService: BescheidService,
+    private readonly formService: BescheidFormService,
+  ) {
+    this.bescheidResource = dialogData.bescheidResource;
+  }
+
+  public save(): void {
+    this.saveStateResource$ = this.formService.submit().pipe(tapOnCommandSuccessfullyDone(() => this.closeDialogWithWizard()));
+  }
+
+  public cancel(): void {
+    if (isNotNil(this.bescheidResource)) {
+      this.deleteStateResource$ = this.bescheidService
+        .bescheidVerwerfen()
+        .pipe(tapOnCommandSuccessfullyDone(() => this.closeDialogWithWizard()));
+    } else {
+      this.closeDialogWithWizard();
+    }
+  }
+
+  closeDialogWithWizard(): void {
+    this.dialogRef.close({ closeWizard: true });
+  }
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..e922efca768811f976d2a2fcc77e219e60ba54b1
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.html
@@ -0,0 +1,12 @@
+<div class="mt-2 grid h-full grid-cols-[min-content_1fr_1fr] gap-7">
+  <alfa-bescheid-wizard-stepper [activeStep]="bescheidWizardStep.DokumenteHochladen"></alfa-bescheid-wizard-stepper>
+  <div>
+    <alfa-bescheid-wizard-step-title label="Antrag bescheiden" [inactiveStep]="true"></alfa-bescheid-wizard-step-title>
+    <alfa-bescheid-wizard-step-title label="Dokumente hochladen"></alfa-bescheid-wizard-step-title>
+    <alfa-bescheid-wizard-dokumente-hochladen-form></alfa-bescheid-wizard-dokumente-hochladen-form>
+  </div>
+  <alfa-bescheid-wizard-summary>
+    <alfa-bescheid-wizard-antrag-bescheiden-summary></alfa-bescheid-wizard-antrag-bescheiden-summary>
+    <alfa-bescheid-wizard-dokumente-hochladen-summary></alfa-bescheid-wizard-dokumente-hochladen-summary>
+  </alfa-bescheid-wizard-summary>
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0ccc4edf5232f58f2f191cecc7d15076e08c13fe
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.spec.ts
@@ -0,0 +1,68 @@
+import { BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { getElementFromFixtureByType } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MockComponent } from 'ng-mocks';
+import { BescheidWizardAntragBescheidenSummaryComponent } from '../antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component';
+import { BescheidWizardStepTitleComponent } from '../step-title/bescheid-wizard-step-title.component';
+import { BescheidWizardStepperComponent } from '../stepper/bescheid-wizard-stepper.component';
+import { BescheidWizardSummaryComponent } from '../summary/bescheid-wizard-summary.component';
+import { BescheidWizardDokumenteHochladenComponent } from './bescheid-wizard-dokumente-hochladen.component';
+import { BescheidWizardDokumenteHochladenFormComponent } from './form/bescheid-wizard-dokumente-hochladen-form.component';
+import { BescheidWizardDokumenteHochladenSummaryComponent } from './summary/bescheid-wizard-dokumente-hochladen-summary.component';
+
+describe('BescheidWizardDokumenteHochladenComponent', () => {
+  let component: BescheidWizardDokumenteHochladenComponent;
+  let fixture: ComponentFixture<BescheidWizardDokumenteHochladenComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [
+        BescheidWizardDokumenteHochladenComponent,
+        MockComponent(BescheidWizardSummaryComponent),
+        MockComponent(BescheidWizardAntragBescheidenSummaryComponent),
+        MockComponent(BescheidWizardDokumenteHochladenSummaryComponent),
+        MockComponent(BescheidWizardStepTitleComponent),
+        MockComponent(BescheidWizardDokumenteHochladenFormComponent),
+        MockComponent(BescheidWizardStepperComponent),
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardDokumenteHochladenComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('alfa-bescheid-wizard-stepper', () => {
+      function getElementComponent(): BescheidWizardStepperComponent {
+        return getElementFromFixtureByType(fixture, BescheidWizardStepperComponent);
+      }
+
+      describe('input', () => {
+        it('should set activeStep', () => {
+          fixture.detectChanges();
+
+          expect(getElementComponent().activeStep).toBe(BescheidWizardStep.DokumenteHochladen);
+        });
+      });
+    });
+
+    describe('alfa-bescheid-wizard-step-title', () => {
+      function getElementComponent(): BescheidWizardStepTitleComponent {
+        return getElementFromFixtureByType(fixture, BescheidWizardStepTitleComponent);
+      }
+
+      describe('input', () => {
+        it('should set inactiveStep', () => {
+          fixture.detectChanges();
+
+          expect(getElementComponent().inactiveStep).toBeTruthy();
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3692f49cd9aa9268a6766928f34abb01b40d007b
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component.ts
@@ -0,0 +1,10 @@
+import { BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-dokumente-hochladen',
+  templateUrl: './bescheid-wizard-dokumente-hochladen.component.html',
+})
+export class BescheidWizardDokumenteHochladenComponent {
+  public readonly bescheidWizardStep = BescheidWizardStep;
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..4bd1961e89455800dbdddd34d3de0e7904f9479a
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.html
@@ -0,0 +1 @@
+<p>bescheid-wizard-dokumente-hochladen-form works!</p>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..417a480c13b49e280112f8a4a85e69663902b722
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BescheidWizardDokumenteHochladenFormComponent } from './bescheid-wizard-dokumente-hochladen-form.component';
+
+describe('BescheidWizardDokumenteHochladenFormComponent', () => {
+  let component: BescheidWizardDokumenteHochladenFormComponent;
+  let fixture: ComponentFixture<BescheidWizardDokumenteHochladenFormComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardDokumenteHochladenFormComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardDokumenteHochladenFormComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..63df23e526cb61c40dbf89b8c459da46d6f6d836
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-dokumente-hochladen-form',
+  templateUrl: './bescheid-wizard-dokumente-hochladen-form.component.html',
+})
+export class BescheidWizardDokumenteHochladenFormComponent {}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..a1b71d424a4b35b04bf8b0aee379001bc748bd21
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.html
@@ -0,0 +1 @@
+<p>bescheid-wizard-dokumente-hochladen-summary works!</p>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..06b8b521caf49c7ff4f93ffa573dbd1301eb7c4a
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BescheidWizardDokumenteHochladenSummaryComponent } from './bescheid-wizard-dokumente-hochladen-summary.component';
+
+describe('BescheidWizardDokumenteHochladenSummaryComponent', () => {
+  let component: BescheidWizardDokumenteHochladenSummaryComponent;
+  let fixture: ComponentFixture<BescheidWizardDokumenteHochladenSummaryComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardDokumenteHochladenSummaryComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardDokumenteHochladenSummaryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b2d4ba96fc074645474734a6d9a68e2f030e6eeb
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-dokumente-hochladen-summary',
+  templateUrl: './bescheid-wizard-dokumente-hochladen-summary.component.html',
+})
+export class BescheidWizardDokumenteHochladenSummaryComponent {}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..637fb2235c8c3971f1f0aa961dc5ad64e0aa58c0
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.html
@@ -0,0 +1,3 @@
+<div class="text-base font-bold text-primary-600" data-test-class="step-caption" [class.min-h-28]="inactiveStep">
+  {{ label }}
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..854259fea8c01efb45c4a5d4e7a1e23f4520bbc0
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BescheidWizardStepTitleComponent } from './bescheid-wizard-step-title.component';
+
+describe('BescheidWizardStepTitleComponent', () => {
+  let component: BescheidWizardStepTitleComponent;
+  let fixture: ComponentFixture<BescheidWizardStepTitleComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardStepTitleComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardStepTitleComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b2df6947c1cd9ce898d9f9400f967c403291f149
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component.ts
@@ -0,0 +1,10 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-step-title',
+  templateUrl: './bescheid-wizard-step-title.component.html',
+})
+export class BescheidWizardStepTitleComponent {
+  @Input() label: string;
+  @Input() inactiveStep: boolean = false;
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..cfdb969637c673c10e0697ceff8500be625d6c6f
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.html
@@ -0,0 +1,9 @@
+<div role="tablist">
+  <alfa-bescheid-wizard-step
+    *ngFor="let step of steps"
+    [activeStep]="activeStep"
+    [step]="step"
+    (stepChange)="stepChange.emit($event)"
+    [attr.data-test-id]="'wizard-step-' + step"
+  ></alfa-bescheid-wizard-step>
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a964c6ed04e417cd6ab487ce18baa9447391b96e
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.spec.ts
@@ -0,0 +1,151 @@
+import { BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { getElementComponentFromFixtureByCss, triggerEvent } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MockComponent } from 'ng-mocks';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import { BescheidWizardStepperComponent } from './bescheid-wizard-stepper.component';
+import { BescheidWizardStepComponent } from './step/bescheid-wizard-step.component';
+
+describe('BescheidWizardStepperComponent', () => {
+  let component: BescheidWizardStepperComponent;
+  let fixture: ComponentFixture<BescheidWizardStepperComponent>;
+
+  const antragBescheidenWizardStep: string = getDataTestIdOf('wizard-step-' + BescheidWizardStep.AntragBescheiden);
+  const dokumenteHochladenWizardStep: string = getDataTestIdOf('wizard-step-' + BescheidWizardStep.DokumenteHochladen);
+  const bescheidVersendenWizardStep: string = getDataTestIdOf('wizard-step-' + BescheidWizardStep.BescheidVersenden);
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardStepperComponent, MockComponent(BescheidWizardStepComponent)],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardStepperComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should have number of steps', () => {
+    expect(component.steps).toEqual([
+      BescheidWizardStep.AntragBescheiden,
+      BescheidWizardStep.DokumenteHochladen,
+      BescheidWizardStep.BescheidVersenden,
+    ]);
+  });
+
+  describe('template', () => {
+    describe('alfa-bescheid-wizard-step', () => {
+      describe('input', () => {
+        it('should set activeStep for antrag bescheiden step', () => {
+          component.activeStep = 2;
+
+          fixture.detectChanges();
+
+          const step: BescheidWizardStepComponent = getElementComponentFromFixtureByCss<BescheidWizardStepComponent>(
+            fixture,
+            antragBescheidenWizardStep,
+          );
+          expect(step.activeStep).toEqual(component.activeStep);
+        });
+
+        it('should set activeStep for dokumente hochladen step', () => {
+          component.activeStep = 2;
+
+          fixture.detectChanges();
+
+          const step: BescheidWizardStepComponent = getElementComponentFromFixtureByCss<BescheidWizardStepComponent>(
+            fixture,
+            dokumenteHochladenWizardStep,
+          );
+          expect(step.activeStep).toEqual(component.activeStep);
+        });
+
+        it('should set activeStep for bescheid versenden step', () => {
+          component.activeStep = 2;
+
+          fixture.detectChanges();
+
+          const step: BescheidWizardStepComponent = getElementComponentFromFixtureByCss<BescheidWizardStepComponent>(
+            fixture,
+            bescheidVersendenWizardStep,
+          );
+          expect(step.activeStep).toEqual(component.activeStep);
+        });
+
+        it('should set step for antrag bescheiden', () => {
+          fixture.detectChanges();
+
+          const step: BescheidWizardStepComponent = getElementComponentFromFixtureByCss<BescheidWizardStepComponent>(
+            fixture,
+            antragBescheidenWizardStep,
+          );
+          expect(step.step).toEqual(BescheidWizardStep.AntragBescheiden);
+        });
+
+        it('should set step for dokumente hochladen', () => {
+          fixture.detectChanges();
+
+          const step: BescheidWizardStepComponent = getElementComponentFromFixtureByCss<BescheidWizardStepComponent>(
+            fixture,
+            dokumenteHochladenWizardStep,
+          );
+          expect(step.step).toEqual(BescheidWizardStep.DokumenteHochladen);
+        });
+
+        it('should set step for bescheid versenden', () => {
+          fixture.detectChanges();
+
+          const step: BescheidWizardStepComponent = getElementComponentFromFixtureByCss<BescheidWizardStepComponent>(
+            fixture,
+            bescheidVersendenWizardStep,
+          );
+          expect(step.step).toEqual(BescheidWizardStep.BescheidVersenden);
+        });
+      });
+
+      describe('output', () => {
+        it('should emit stepChange for antrag bescheiden step', () => {
+          component.stepChange.emit = jest.fn();
+
+          triggerEvent({
+            fixture,
+            name: 'stepChange',
+            elementSelector: antragBescheidenWizardStep,
+            data: BescheidWizardStep.DokumenteHochladen,
+          });
+
+          expect(component.stepChange.emit).toHaveBeenCalledWith(BescheidWizardStep.DokumenteHochladen);
+        });
+
+        it('should emit stepChange for dokumente hochladen step', () => {
+          component.stepChange.emit = jest.fn();
+
+          triggerEvent({
+            fixture,
+            name: 'stepChange',
+            elementSelector: dokumenteHochladenWizardStep,
+            data: BescheidWizardStep.DokumenteHochladen,
+          });
+
+          expect(component.stepChange.emit).toHaveBeenCalledWith(BescheidWizardStep.DokumenteHochladen);
+        });
+
+        it('should emit stepChange for bescheid versenden step', () => {
+          component.stepChange.emit = jest.fn();
+
+          triggerEvent({
+            fixture,
+            name: 'stepChange',
+            elementSelector: bescheidVersendenWizardStep,
+            data: BescheidWizardStep.DokumenteHochladen,
+          });
+
+          expect(component.stepChange.emit).toHaveBeenCalledWith(BescheidWizardStep.DokumenteHochladen);
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bd2343419cc4cbf386721324c58576a5bc4ef214
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component.ts
@@ -0,0 +1,18 @@
+import { BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-stepper',
+  templateUrl: './bescheid-wizard-stepper.component.html',
+})
+export class BescheidWizardStepperComponent {
+  @Input() activeStep: BescheidWizardStep;
+
+  @Output() stepChange: EventEmitter<BescheidWizardStep> = new EventEmitter<BescheidWizardStep>();
+
+  public readonly steps: BescheidWizardStep[] = [
+    BescheidWizardStep.AntragBescheiden,
+    BescheidWizardStep.DokumenteHochladen,
+    BescheidWizardStep.BescheidVersenden,
+  ];
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..731c9cbbfa08b5112a536938d06c1d5471d53892
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.html
@@ -0,0 +1,57 @@
+<div class="relative z-10 flex min-h-28 flex-col items-center">
+  <div
+    class="-z-1 absolute w-1"
+    [ngClass]="
+      step === bescheidWizardStep.AntragBescheiden ?
+        isPrevious() ? 'bottom-0 top-2 bg-primary-600'
+        : 'bottom-0 top-2 bg-gray-500'
+      : step === bescheidWizardStep.DokumenteHochladen ?
+        isPrevious() ? 'bottom-0 top-0 bg-primary-600'
+        : 'bottom-0 top-0 bg-gray-500'
+      : step === bescheidWizardStep.BescheidVersenden ?
+        isActive() ? 'top-0 h-2  bg-primary-600'
+        : 'top-0 h-2 bg-gray-500'
+      : ''
+    "
+    aria-hidden="true"
+  ></div>
+
+  <button
+    class="z-10 flex"
+    (click)="clickHandler(step)"
+    [ngClass]="isPrevious() ? 'cursor-pointer' : 'cursor-default'"
+    [attr.data-test-id]="
+      step === bescheidWizardStep.AntragBescheiden ? 'step-1-button'
+      : step === bescheidWizardStep.DokumenteHochladen ? 'step-2-button'
+      : step === bescheidWizardStep.BescheidVersenden ? 'step-3-button'
+      : ''
+    "
+    role="tab"
+    [attr.aria-selected]="isActive()"
+    [attr.aria-disabled]="!isActive()"
+    attr.aria-controls="vorgang-detail-bescheiden-step-content-{{ step }}"
+    [tabindex]="
+      isActive() ? '0'
+      : isPrevious() ? '0'
+      : '-1'
+    "
+    [attr.aria-label]="
+      step === bescheidWizardStep.AntragBescheiden ? 'Step 1. Antrag bescheiden'
+      : step === bescheidWizardStep.DokumenteHochladen ? 'Step 2. Dokumente hinzufügen'
+      : step === bescheidWizardStep.BescheidVersenden ? 'Step 3. Bescheid versenden'
+      : ''
+    "
+  >
+    <span
+      class="flex size-10 items-center justify-center rounded-full"
+      [ngClass]="isActive() ? 'border-4 border-primary-600 bg-background-50' : 'border-transparent bg-transparent'"
+    >
+      <span
+        class="flex size-7 items-center justify-center rounded-full text-sm text-whitetext"
+        [ngClass]="isPrevious() || isActive() ? 'bg-primary-600' : 'bg-gray-500'"
+      >
+        {{ step }}
+      </span>
+    </span>
+  </button>
+</div>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8d880a7efefe4f8e37c492bf5905d7008ee8ce16
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.spec.ts
@@ -0,0 +1,126 @@
+import { BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BescheidWizardStepComponent } from './bescheid-wizard-step.component';
+
+describe('BescheidWizardStepComponent', () => {
+  let component: BescheidWizardStepComponent;
+  let fixture: ComponentFixture<BescheidWizardStepComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardStepComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardStepComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('isActive', () => {
+    beforeEach(() => {
+      component.activeStep = BescheidWizardStep.DokumenteHochladen;
+    });
+
+    it('return true if step equals activeStep', () => {
+      component.step = BescheidWizardStep.DokumenteHochladen;
+
+      const isActive: boolean = component.isActive();
+
+      expect(isActive).toBeTruthy();
+    });
+
+    it('return false if step not equals activeStep', () => {
+      component.step = BescheidWizardStep.AntragBescheiden;
+
+      const isActive: boolean = component.isActive();
+
+      expect(isActive).toBeFalsy();
+    });
+  });
+
+  describe('isPrevious', () => {
+    beforeEach(() => {
+      component.activeStep = BescheidWizardStep.DokumenteHochladen;
+    });
+
+    it('return true if step is less than activeStep', () => {
+      component.step = BescheidWizardStep.AntragBescheiden;
+
+      const isPrevious: boolean = component.isPrevious();
+
+      expect(isPrevious).toBeTruthy();
+    });
+
+    it('return false if step equals activeStep', () => {
+      component.step = BescheidWizardStep.DokumenteHochladen;
+
+      const isPrevious: boolean = component.isPrevious();
+
+      expect(isPrevious).toBeFalsy();
+    });
+
+    it('return false if step is greater than activeStep', () => {
+      component.step = BescheidWizardStep.BescheidVersenden;
+
+      const isPrevious: boolean = component.isPrevious();
+
+      expect(isPrevious).toBeFalsy();
+    });
+  });
+
+  describe('isNext', () => {
+    beforeEach(() => {
+      component.activeStep = BescheidWizardStep.DokumenteHochladen;
+    });
+
+    it('return false if step is less than activeStep', () => {
+      component.step = BescheidWizardStep.AntragBescheiden;
+
+      const isNext: boolean = component.isNext();
+
+      expect(isNext).toBeFalsy();
+    });
+
+    it('return false if step equals activeStep', () => {
+      component.step = BescheidWizardStep.DokumenteHochladen;
+
+      const isNext: boolean = component.isNext();
+
+      expect(isNext).toBeFalsy();
+    });
+
+    it('return true if step is greater than activeStep', () => {
+      component.step = BescheidWizardStep.BescheidVersenden;
+
+      const isNext: boolean = component.isNext();
+
+      expect(isNext).toBeTruthy();
+    });
+  });
+
+  describe('clickHandler', () => {
+    beforeEach(() => {
+      component.stepChange.emit = jest.fn();
+    });
+
+    it('should emit step', () => {
+      component.isPrevious = jest.fn().mockReturnValue(true);
+
+      component.clickHandler(BescheidWizardStep.AntragBescheiden);
+
+      expect(component.stepChange.emit).toHaveBeenCalledWith(BescheidWizardStep.AntragBescheiden);
+    });
+
+    it('should not emit step', () => {
+      component.isPrevious = jest.fn().mockReturnValue(false);
+
+      component.clickHandler(BescheidWizardStep.AntragBescheiden);
+
+      expect(component.stepChange.emit).not.toHaveBeenCalled();
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ddb427d422f3e5f92a71a56445543c6281a4a426
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component.ts
@@ -0,0 +1,33 @@
+import { BescheidWizardStep } from '@alfa-client/bescheid-shared';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-step',
+  templateUrl: './bescheid-wizard-step.component.html',
+})
+export class BescheidWizardStepComponent {
+  @Input() step: BescheidWizardStep;
+  @Input() activeStep: BescheidWizardStep;
+
+  @Output() stepChange: EventEmitter<BescheidWizardStep> = new EventEmitter<BescheidWizardStep>();
+
+  public readonly bescheidWizardStep = BescheidWizardStep;
+
+  public clickHandler(step: BescheidWizardStep): void {
+    if (this.isPrevious()) {
+      this.stepChange.emit(step);
+    }
+  }
+
+  public isActive(): boolean {
+    return this.step === this.activeStep;
+  }
+
+  public isPrevious(): boolean {
+    return this.step < this.activeStep;
+  }
+
+  public isNext(): boolean {
+    return this.step > this.activeStep;
+  }
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..9404884a6510a2e16cb20b1fd4d81c5701f89ce7
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.html
@@ -0,0 +1,4 @@
+<section class="flex h-full w-full flex-col overflow-auto rounded-xl bg-background-100 px-4 py-5">
+  <h3 class="mb-4 text-base font-bold text-primary-600">Bescheid</h3>
+  <ng-content></ng-content>
+</section>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3f38f047d8dc3e1233ea44b3c8c0c73418b31f03
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { BescheidWizardSummaryComponent } from './bescheid-wizard-summary.component';
+
+describe('BescheidWizardSummaryTitleComponent', () => {
+  let component: BescheidWizardSummaryComponent;
+  let fixture: ComponentFixture<BescheidWizardSummaryComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardSummaryComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardSummaryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8cf4be6c484c0989f294d8384748707444b812c3
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-summary',
+  templateUrl: './bescheid-wizard-summary.component.html',
+})
+export class BescheidWizardSummaryComponent {}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..0baf1ff340c2b506157e0c038d85bcb44c894279
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.html
@@ -0,0 +1,10 @@
+<ods-button-with-spinner
+  [stateResource]="submitStateResource"
+  (clickEmitter)="clickEmitter.emit()"
+  variant="primary"
+  size="medium"
+  class="mt-8 flex"
+  data-test-id="bescheid-weiter-button"
+  text="Weiter"
+>
+</ods-button-with-spinner>
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fe96a125921eb3a4625480d865e1614395b27940
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.spec.ts
@@ -0,0 +1,65 @@
+import { CommandResource } from '@alfa-client/command-shared';
+import { createStateResource, StateResource } from '@alfa-client/tech-shared';
+import { getElementFromFixtureByType, Mock, mock, triggerEvent, useFromMock } from '@alfa-client/test-utils';
+import { EventEmitter } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ButtonWithSpinnerComponent } from '@ods/component';
+import { MockComponent } from 'ng-mocks';
+import { createCommandResource } from '../../../../../../command-shared/test/command';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import { BescheidWizardWeiterButtonComponent } from './bescheid-wizard-weiter-button.component';
+
+describe('BescheidWizardWeiterButtonComponent', () => {
+  let component: BescheidWizardWeiterButtonComponent;
+  let fixture: ComponentFixture<BescheidWizardWeiterButtonComponent>;
+
+  const button: string = getDataTestIdOf('bescheid-weiter-button');
+
+  let clickEmitter: Mock<EventEmitter<MouseEvent>>;
+
+  beforeEach(() => {
+    clickEmitter = mock(EventEmitter);
+  });
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BescheidWizardWeiterButtonComponent, MockComponent(ButtonWithSpinnerComponent)],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BescheidWizardWeiterButtonComponent);
+    component = fixture.componentInstance;
+    component.clickEmitter = useFromMock(clickEmitter);
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('ods-button-with-spinner', () => {
+      describe('input', () => {
+        it('should set submitStateResource', () => {
+          const stateResource: StateResource<CommandResource> = createStateResource(createCommandResource(), true);
+          component.submitStateResource = stateResource;
+
+          fixture.detectChanges();
+
+          expect(getElementFromFixtureByType(fixture, ButtonWithSpinnerComponent).stateResource).toEqual(stateResource);
+        });
+      });
+
+      describe('output', () => {
+        it('should emit click', () => {
+          triggerEvent({
+            fixture,
+            name: 'clickEmitter',
+            elementSelector: button,
+          });
+
+          expect(clickEmitter.emit).toHaveBeenCalled();
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8348ca2bc0e80cd65557cfa8ae20b705a5e09598
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component.ts
@@ -0,0 +1,13 @@
+import { StateResource } from '@alfa-client/tech-shared';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+
+@Component({
+  selector: 'alfa-bescheid-wizard-weiter-button',
+  templateUrl: './bescheid-wizard-weiter-button.component.html',
+})
+export class BescheidWizardWeiterButtonComponent {
+  @Input() submitStateResource: StateResource<Resource>;
+
+  @Output() clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.spec.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..31a7953ddbbe01a16efe3ef77db557379ab94995
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.spec.ts
@@ -0,0 +1,142 @@
+import { Bescheid, BescheidLinkRel, BescheidResource, BescheidSendBy, BescheidService } from '@alfa-client/bescheid-shared';
+import { formatForDatabase } from '@alfa-client/tech-shared';
+import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
+import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { registerLocaleData } from '@angular/common';
+import localeDe from '@angular/common/locales/de';
+import { UntypedFormBuilder } from '@angular/forms';
+import { faker } from '@faker-js/faker';
+import { ResourceUri } from '@ngxp/rest';
+import { EMPTY, Observable, of } from 'rxjs';
+import { createBescheid, createBescheidResource } from '../../../../bescheid-shared/src/test/bescheid';
+import { singleCold } from '../../../../tech-shared/test/marbles';
+import { createVorgangWithEingangResource } from '../../../../vorgang-shared/test/vorgang';
+import { BescheidFormService } from './bescheid.formservice';
+
+registerLocaleData(localeDe);
+
+describe('BescheidFormService', () => {
+  let service: BescheidFormService;
+  let bescheidService: Mock<BescheidService>;
+  const now: Date = new Date();
+  Date.now = jest.fn().mockReturnValue(now);
+  const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource();
+
+  beforeEach(() => {
+    bescheidService = mock(BescheidService);
+    bescheidService.createBescheid.mockReturnValue(of(EMPTY));
+    service = new BescheidFormService(new UntypedFormBuilder(), useFromMock(bescheidService));
+    service.setVorgangWithEingangResource(vorgangWithEingangResource);
+  });
+
+  describe('doSubmit', () => {
+    it('should create bescheid', () => {
+      const formValue: Bescheid = createBescheid();
+      service.getBescheidFormValue = jest.fn().mockReturnValue(formValue);
+
+      service.submit();
+
+      expect(bescheidService.createBescheid).toHaveBeenCalledWith(vorgangWithEingangResource, formValue);
+    });
+  });
+
+  describe('patchValues', () => {
+    let bescheidResource: BescheidResource;
+    let patch: jest.Mock;
+
+    beforeEach(() => {
+      bescheidResource = createBescheidResource();
+      patch = service.patch = jest.fn();
+    });
+
+    it('should patch', () => {
+      service.patchValues(bescheidResource);
+
+      expect(patch).toHaveBeenCalledWith({
+        [BescheidFormService.FIELD_BESCHIEDEN_AM]: bescheidResource.beschiedenAm,
+        [BescheidFormService.FIELD_BEWILLIGT]: String(bescheidResource.bewilligt),
+        [BescheidFormService.FIELD_BESCHEID_DOCUMENT]: null,
+        [BescheidFormService.FIELD_SEND_BY]: String(bescheidResource.sendBy),
+        [BescheidFormService.FIELD_NACHRICHT_SUBJECT]: bescheidResource.nachrichtSubject,
+        [BescheidFormService.FIELD_NACHRICHT_TEXT]: bescheidResource.nachrichtText,
+      });
+    });
+
+    it('should patch sendBy to default', () => {
+      service.patchValues({
+        ...bescheidResource,
+        sendBy: undefined,
+      });
+
+      expect(patch).toHaveBeenCalledWith({
+        [BescheidFormService.FIELD_BESCHIEDEN_AM]: bescheidResource.beschiedenAm,
+        [BescheidFormService.FIELD_BEWILLIGT]: String(bescheidResource.bewilligt),
+        [BescheidFormService.FIELD_SEND_BY]: BescheidSendBy.NACHRICHT,
+        [BescheidFormService.FIELD_BESCHEID_DOCUMENT]: null,
+        [BescheidFormService.FIELD_NACHRICHT_SUBJECT]: bescheidResource.nachrichtSubject,
+        [BescheidFormService.FIELD_NACHRICHT_TEXT]: bescheidResource.nachrichtText,
+      });
+    });
+
+    it('should patch bescheid document uri', () => {
+      const bescheidDocumentUri: ResourceUri = faker.internet.url();
+      service.patchValues({
+        ...bescheidResource,
+        _links: {
+          ...bescheidResource._links,
+          [BescheidLinkRel.BESCHEID_DOCUMENT]: { href: bescheidDocumentUri },
+        },
+      });
+
+      expect(patch).toHaveBeenCalledWith({
+        [BescheidFormService.FIELD_BESCHIEDEN_AM]: bescheidResource.beschiedenAm,
+        [BescheidFormService.FIELD_BEWILLIGT]: String(bescheidResource.bewilligt),
+        [BescheidFormService.FIELD_SEND_BY]: BescheidSendBy.NACHRICHT,
+        [BescheidFormService.FIELD_BESCHEID_DOCUMENT]: bescheidDocumentUri,
+        [BescheidFormService.FIELD_NACHRICHT_SUBJECT]: bescheidResource.nachrichtSubject,
+        [BescheidFormService.FIELD_NACHRICHT_TEXT]: bescheidResource.nachrichtText,
+      });
+    });
+
+    it('should patch attachments', () => {
+      service.patchValues(bescheidResource);
+
+      expect(service.getFormValue().attachments).toEqual(bescheidResource.attachments);
+    });
+  });
+
+  describe('getBescheidFormValueChanges', () => {
+    const bescheid: Bescheid = createBescheid();
+
+    beforeEach(() => {
+      service.getBescheidFormValue = jest.fn().mockReturnValue(bescheid);
+    });
+
+    it('should emit bescheid', () => {
+      const bescheidFormValueChanges$: Observable<Bescheid> = service.getBescheidFormValueChanges();
+
+      expect(bescheidFormValueChanges$).toBeObservable(singleCold(bescheid));
+    });
+  });
+
+  describe('getBescheidFormValue', () => {
+    beforeEach(() => {
+      service.getFormValue = jest.fn().mockReturnValue({ beschiedenAm: now, bewilligt: 'true' });
+    });
+
+    it('should getFormValue', () => {
+      service.getBescheidFormValue();
+
+      expect(service.getFormValue).toHaveBeenCalled();
+    });
+
+    it('should return bescheid', () => {
+      const bescheid: Bescheid = service.getBescheidFormValue();
+
+      expect(bescheid).toEqual({
+        bewilligt: true,
+        beschiedenAm: formatForDatabase(now),
+      } as Bescheid);
+    });
+  });
+});
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.ts b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ca522ee6a9d6dae7505db2630572da013258d13f
--- /dev/null
+++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid.formservice.ts
@@ -0,0 +1,93 @@
+import { Bescheid, BescheidLinkRel, BescheidResource, BescheidSendBy, BescheidService } from '@alfa-client/bescheid-shared';
+import { AbstractFormService, StateResource, convertToBoolean, formatForDatabase } from '@alfa-client/tech-shared';
+import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { Injectable } from '@angular/core';
+import { UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
+import { Resource, ResourceUri, getUrl, hasLink } from '@ngxp/rest';
+import { isUndefined } from 'lodash-es';
+import { Observable, startWith } from 'rxjs';
+
+@Injectable()
+export class BescheidFormService extends AbstractFormService {
+  static readonly FIELD_BESCHIEDEN_AM = 'beschiedenAm';
+  static readonly FIELD_BEWILLIGT = 'bewilligt';
+  static readonly FIELD_BESCHEID_DOCUMENT = 'bescheidDocument';
+  static readonly FIELD_ATTACHMENTS = 'attachments';
+  public static readonly FIELD_SEND_BY = 'sendBy';
+  static readonly FIELD_NACHRICHT_SUBJECT = 'nachrichtSubject';
+  static readonly FIELD_NACHRICHT_TEXT = 'nachrichtText';
+
+  static readonly FIELD_PATH_PREFIX = 'command.body';
+
+  private vorgangWithEingangResource: VorgangWithEingangResource;
+
+  constructor(
+    formBuilder: UntypedFormBuilder,
+    private readonly bescheidService: BescheidService,
+  ) {
+    super(formBuilder);
+  }
+
+  protected initForm(): UntypedFormGroup {
+    return this.formBuilder.group({
+      [BescheidFormService.FIELD_BESCHIEDEN_AM]: new UntypedFormControl(new Date(Date.now())),
+      [BescheidFormService.FIELD_BEWILLIGT]: new UntypedFormControl('true'),
+      [BescheidFormService.FIELD_SEND_BY]: new UntypedFormControl(BescheidSendBy.NACHRICHT),
+      [BescheidFormService.FIELD_BESCHEID_DOCUMENT]: new UntypedFormControl(null),
+      [BescheidFormService.FIELD_ATTACHMENTS]: new UntypedFormArray([]),
+      [BescheidFormService.FIELD_NACHRICHT_SUBJECT]: new UntypedFormControl(''),
+      [BescheidFormService.FIELD_NACHRICHT_TEXT]: new UntypedFormControl(''),
+    });
+  }
+
+  protected doSubmit(): Observable<StateResource<Resource>> {
+    return this.bescheidService.createBescheid(this.vorgangWithEingangResource, this.getBescheidFormValue());
+  }
+
+  protected getPathPrefix(): string {
+    return BescheidFormService.FIELD_PATH_PREFIX;
+  }
+
+  public patchValues(bescheid: BescheidResource): void {
+    const bescheidDocumentUri: ResourceUri = this.getBescheidDocumentUri(bescheid);
+    this.bescheidService.setDocumentUri(bescheidDocumentUri);
+    this.patch({
+      [BescheidFormService.FIELD_BESCHIEDEN_AM]: bescheid.beschiedenAm,
+      [BescheidFormService.FIELD_BEWILLIGT]: String(bescheid.bewilligt),
+      [BescheidFormService.FIELD_BESCHEID_DOCUMENT]: bescheidDocumentUri,
+      [BescheidFormService.FIELD_SEND_BY]: isUndefined(bescheid.sendBy) ? BescheidSendBy.NACHRICHT : bescheid.sendBy,
+      [BescheidFormService.FIELD_NACHRICHT_SUBJECT]: bescheid.nachrichtSubject,
+      [BescheidFormService.FIELD_NACHRICHT_TEXT]: bescheid.nachrichtText,
+    });
+    bescheid.attachments.forEach((attachmentLink) =>
+      (this.form.controls[BescheidFormService.FIELD_ATTACHMENTS] as UntypedFormArray).push(
+        new UntypedFormControl(attachmentLink),
+      ),
+    );
+  }
+
+  private getBescheidDocumentUri(bescheid: BescheidResource): ResourceUri | null {
+    if (hasLink(bescheid, BescheidLinkRel.BESCHEID_DOCUMENT)) {
+      return getUrl(bescheid, BescheidLinkRel.BESCHEID_DOCUMENT);
+    }
+    return null;
+  }
+
+  public getBescheidFormValueChanges(): Observable<Bescheid> {
+    return this.form.valueChanges.pipe(startWith(this.getBescheidFormValue()));
+  }
+
+  public getBescheidFormValue(): Bescheid {
+    const value: any = this.getFormValue();
+    return {
+      ...value,
+      beschiedenAm: formatForDatabase(value.beschiedenAm),
+      bewilligt: convertToBoolean(value.bewilligt),
+      attachments: value.attachments,
+    };
+  }
+
+  public setVorgangWithEingangResource(vorgangWithEingangResource: VorgangWithEingangResource): void {
+    this.vorgangWithEingangResource = vorgangWithEingangResource;
+  }
+}
diff --git a/alfa-client/libs/bescheid/src/lib/bescheid.module.ts b/alfa-client/libs/bescheid/src/lib/bescheid.module.ts
index e80dff3c3e0610a0d46b4b5babfa41c1d713d01a..0b21469bbe360803b4356a8b03a23539b4073e97 100644
--- a/alfa-client/libs/bescheid/src/lib/bescheid.module.ts
+++ b/alfa-client/libs/bescheid/src/lib/bescheid.module.ts
@@ -13,12 +13,31 @@ import { DocumentInBescheidContainerComponent } from './bescheid-list-in-vorgang
 import { BeschiedenDateContainerComponent } from './beschieden-date-in-vorgang-container/beschieden-date-container/beschieden-date-container.component';
 import { BeschiedenDateInVorgangContainerComponent } from './beschieden-date-in-vorgang-container/beschieden-date-in-vorgang-container.component';
 
+import { ButtonWithSpinnerComponent } from '@ods/component';
 import {
   BescheidStatusTextComponent,
   BescheidWrapperComponent,
+  ButtonComponent,
   CloseIconComponent,
+  RadioButtonCardComponent,
   StampIconComponent,
 } from '@ods/system';
+import { BescheidWizardContainerComponent } from './bescheid-wizard-container/bescheid-wizard-container.component';
+import { BescheidWizardAbschliessenButtonComponent } from './bescheid-wizard-container/bescheid-wizard/abschliessen-button/bescheid-wizard-abschliessen-button.component';
+import { BescheidWizardAbschliessenDialogContainerComponent } from './bescheid-wizard-container/bescheid-wizard/abschliessen-dialog-container/bescheid-wizard-abschliessen-dialog-container.component';
+import { BescheidWizardAntragBescheidenComponent } from './bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/bescheid-wizard-antrag-bescheiden.component';
+import { BescheidWizardAntragBescheidenFormComponent } from './bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/form/bescheid-wizard-antrag-bescheiden-form.component';
+import { BescheidWizardAntragBescheidenSummaryComponent } from './bescheid-wizard-container/bescheid-wizard/antrag-bescheiden/summary/bescheid-wizard-antrag-bescheiden-summary.component';
+import { BescheidWizardComponent } from './bescheid-wizard-container/bescheid-wizard/bescheid-wizard.component';
+import { BescheidWizardCancelDialogContainerComponent } from './bescheid-wizard-container/bescheid-wizard/cancel-dialog-container/bescheid-wizard-cancel-dialog-container.component';
+import { BescheidWizardDokumenteHochladenComponent } from './bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/bescheid-wizard-dokumente-hochladen.component';
+import { BescheidWizardDokumenteHochladenFormComponent } from './bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/form/bescheid-wizard-dokumente-hochladen-form.component';
+import { BescheidWizardDokumenteHochladenSummaryComponent } from './bescheid-wizard-container/bescheid-wizard/dokumente-hochladen/summary/bescheid-wizard-dokumente-hochladen-summary.component';
+import { BescheidWizardStepTitleComponent } from './bescheid-wizard-container/bescheid-wizard/step-title/bescheid-wizard-step-title.component';
+import { BescheidWizardStepperComponent } from './bescheid-wizard-container/bescheid-wizard/stepper/bescheid-wizard-stepper.component';
+import { BescheidWizardStepComponent } from './bescheid-wizard-container/bescheid-wizard/stepper/step/bescheid-wizard-step.component';
+import { BescheidWizardSummaryComponent } from './bescheid-wizard-container/bescheid-wizard/summary/bescheid-wizard-summary.component';
+import { BescheidWizardWeiterButtonComponent } from './bescheid-wizard-container/bescheid-wizard/weiter-button/bescheid-wizard-weiter-button.component';
 
 @NgModule({
   imports: [
@@ -32,6 +51,9 @@ import {
     BescheidWrapperComponent,
     StampIconComponent,
     CloseIconComponent,
+    ButtonWithSpinnerComponent,
+    RadioButtonCardComponent,
+    ButtonComponent,
   ],
   declarations: [
     BescheidInVorgangContainerComponent,
@@ -41,6 +63,22 @@ import {
     DocumentInBescheidContainerComponent,
     BeschiedenDateContainerComponent,
     BeschiedenDateInVorgangContainerComponent,
+    BescheidWizardContainerComponent,
+    BescheidWizardComponent,
+    BescheidWizardStepComponent,
+    BescheidWizardStepperComponent,
+    BescheidWizardStepTitleComponent,
+    BescheidWizardSummaryComponent,
+    BescheidWizardWeiterButtonComponent,
+    BescheidWizardCancelDialogContainerComponent,
+    BescheidWizardAntragBescheidenComponent,
+    BescheidWizardAntragBescheidenFormComponent,
+    BescheidWizardAntragBescheidenSummaryComponent,
+    BescheidWizardDokumenteHochladenComponent,
+    BescheidWizardDokumenteHochladenFormComponent,
+    BescheidWizardDokumenteHochladenSummaryComponent,
+    BescheidWizardAbschliessenButtonComponent,
+    BescheidWizardAbschliessenDialogContainerComponent,
   ],
   exports: [
     BescheidInVorgangContainerComponent,
diff --git a/alfa-client/libs/command-shared/test/command.ts b/alfa-client/libs/command-shared/test/command.ts
index 6843ee1d96699bc59ad4aeab4b49f14b63f6cd0b..d0ffa279db7e9a62c14410cba5652806c41b5895 100644
--- a/alfa-client/libs/command-shared/test/command.ts
+++ b/alfa-client/libs/command-shared/test/command.ts
@@ -25,9 +25,17 @@ import { createStateResource, StateResource } from '@alfa-client/tech-shared';
 import { faker } from '@faker-js/faker';
 import { toResource } from 'libs/tech-shared/test/resource';
 import { times } from 'lodash-es';
-import { CommandListLinkRel } from '../src/lib/command.linkrel';
+import { CommandLinkRel, CommandListLinkRel } from '../src/lib/command.linkrel';
 import { CommandErrorMessage } from '../src/lib/command.message';
-import { Command, CommandListResource, CommandOrder, CommandResource, CommandStatus, CreateCommand, CreateCommandProps, } from '../src/lib/command.model';
+import {
+  Command,
+  CommandListResource,
+  CommandOrder,
+  CommandResource,
+  CommandStatus,
+  CreateCommand,
+  CreateCommandProps,
+} from '../src/lib/command.model';
 
 export function createCommand(): Command {
   return {
@@ -68,15 +76,11 @@ export function createCommandErrorResource(linkRelations: string[] = []): Comman
   };
 }
 
-export function createCommandErrorStateResource(
-  linkRelations: string[] = [],
-): StateResource<CommandResource> {
+export function createCommandErrorStateResource(linkRelations: string[] = []): StateResource<CommandResource> {
   return createStateResource(createCommandErrorResource(linkRelations));
 }
 
-export function createCreateCommand(
-  order: CommandOrder = CommandOrder.VORGANG_ANNEHMEN,
-): CreateCommand {
+export function createCreateCommand(order: CommandOrder = CommandOrder.VORGANG_ANNEHMEN): CreateCommand {
   return { order, body: null };
 }
 
@@ -88,3 +92,11 @@ export function createCreateCommandProps(): CreateCommandProps {
     snackBarMessage: faker.word.sample(5),
   };
 }
+
+export function createSuccessfullyDoneCommandStateResource(): StateResource<CommandResource> {
+  return createCommandStateResource([CommandLinkRel.EFFECTED_RESOURCE]);
+}
+
+export function createSuccessfullyDoneCommandResource(): CommandResource {
+  return createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]);
+}
diff --git a/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.spec.ts b/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.spec.ts
index 4848c4005e5493630f498836b2807519da953cbe..bd5d2317e9642c5a633183483b806921e908ca3e 100644
--- a/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.spec.ts
+++ b/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.spec.ts
@@ -1,6 +1,8 @@
+import { ENTER_KEY, ESCAPE_KEY } from '@alfa-client/tech-shared';
 import { getElementFromFixture } from '@alfa-client/test-utils';
-import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
 import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { createKeydownKeyboardEvent } from '../../../../../test-utils/src/lib/keyboard';
 import { DropdownMenuComponent } from './dropdown-menu.component';
 
 describe('DropdownMenuComponent', () => {
@@ -140,27 +142,6 @@ describe('DropdownMenuComponent', () => {
     });
   });
 
-  describe('isEscapeKey', () => {
-    it('should return true', () => {
-      const escapeKeyEvent: KeyboardEvent = {
-        ...new KeyboardEvent('esc'),
-        key: 'Escape',
-      };
-
-      const result: boolean = component.isEscapeKey(escapeKeyEvent);
-
-      expect(result).toBe(true);
-    });
-
-    it('should return false', () => {
-      const keyEvent: KeyboardEvent = new KeyboardEvent('whatever');
-
-      const result: boolean = component.isEscapeKey(keyEvent);
-
-      expect(result).toBe(false);
-    });
-  });
-
   describe('closePopupAndFocusButton', () => {
     beforeEach(() => {
       component.isPopupOpen = true;
@@ -198,11 +179,8 @@ describe('DropdownMenuComponent', () => {
   });
 
   describe('onKeydownHandler', () => {
-    const e: KeyboardEvent = new KeyboardEvent('test');
-
     beforeEach(() => {
       component.closePopupAndFocusButton = jest.fn();
-      component.isEscapeKey = jest.fn();
     });
 
     describe('popup is closed', () => {
@@ -210,10 +188,12 @@ describe('DropdownMenuComponent', () => {
         component.isPopupClosed = jest.fn().mockReturnValue(true);
       });
 
-      it('should not check for escape key', () => {
-        component.onKeydownHandler(e);
+      it('should not close popup', () => {
+        component.closePopupAndFocusButton = jest.fn();
+
+        component.onKeydownHandler(createKeydownKeyboardEvent(ESCAPE_KEY));
 
-        expect(component.isEscapeKey).not.toHaveBeenCalled();
+        expect(component.closePopupAndFocusButton).not.toHaveBeenCalled();
       });
     });
 
@@ -222,22 +202,14 @@ describe('DropdownMenuComponent', () => {
         component.isPopupClosed = jest.fn().mockReturnValue(false);
       });
 
-      it('should check for escape key', () => {
-        component.onKeydownHandler(e);
-
-        expect(component.isEscapeKey).toHaveBeenCalled();
-      });
-
-      it('should handle escape key', () => {
-        component.isEscapeKey = jest.fn().mockReturnValue(true);
-
-        component.onKeydownHandler(e);
+      it('should close popup', () => {
+        component.onKeydownHandler(createKeydownKeyboardEvent(ESCAPE_KEY));
 
         expect(component.closePopupAndFocusButton).toHaveBeenCalled();
       });
 
-      it('should not handle escape key', () => {
-        component.onKeydownHandler(e);
+      it('should not close popup', () => {
+        component.onKeydownHandler(createKeydownKeyboardEvent(ENTER_KEY));
 
         expect(component.closePopupAndFocusButton).not.toHaveBeenCalled();
       });
diff --git a/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts b/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts
index fd81fa2b276da1d907d9993b92e98a9fb76362d0..02a78af00276c13f33a7874dc1781f4c325624b3 100644
--- a/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts
+++ b/alfa-client/libs/design-system/src/lib/dropdown-menu/dropdown-menu/dropdown-menu.component.ts
@@ -1,3 +1,4 @@
+import { isEscapeKey } from '@alfa-client/tech-shared';
 import { CdkTrapFocus } from '@angular/cdk/a11y';
 import { CommonModule } from '@angular/common';
 import { Component, ElementRef, HostListener, Input, ViewChild } from '@angular/core';
@@ -7,7 +8,7 @@ import { twMerge } from 'tailwind-merge';
   selector: 'ods-dropdown-menu',
   standalone: true,
   imports: [CommonModule, CdkTrapFocus],
-  template: `<div class="relative w-fit">
+  template: ` <div class="relative w-fit">
     <button
       [ngClass]="[twMerge('block w-fit outline-2 outline-offset-2 outline-focus', buttonClass)]"
       (click)="handleButtonClick()"
@@ -52,7 +53,7 @@ export class DropdownMenuComponent {
   @HostListener('document:keydown', ['$event'])
   onKeydownHandler(e: KeyboardEvent): void {
     if (this.isPopupClosed()) return;
-    if (this.isEscapeKey(e)) this.closePopupAndFocusButton();
+    if (isEscapeKey(e)) this.closePopupAndFocusButton();
   }
 
   @HostListener('document:click', ['$event'])
@@ -85,10 +86,6 @@ export class DropdownMenuComponent {
     this.buttonRef.nativeElement.focus();
   }
 
-  isEscapeKey(e: KeyboardEvent): boolean {
-    return e.key === 'Escape';
-  }
-
   isPopupClosed(): boolean {
     return !this.isPopupOpen;
   }
diff --git a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts
index b83a6e167dbaabae7a8a6e4b6595086ff48bde93..f8f85ec82f7b0fe16fe4c828de802f913da07c57 100644
--- a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts
+++ b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.spec.ts
@@ -1,8 +1,10 @@
+import { ENTER_KEY, ESCAPE_KEY } from '@alfa-client/tech-shared';
 import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
 import { EventEmitter } from '@angular/core';
 import { ComponentFixture, TestBed, discardPeriodicTasks, fakeAsync, tick } from '@angular/core/testing';
 import { Resource } from '@ngxp/rest';
 import { Subscription } from 'rxjs';
+import { createKeydownKeyboardEvent } from '../../../../../test-utils/src/lib/keyboard';
 import { InstantSearchComponent } from './instant-search.component';
 import { InstantSearchQuery, InstantSearchResult } from './instant-search.model';
 
@@ -391,7 +393,6 @@ describe('InstantSearchComponent', () => {
     beforeEach(() => {
       component.isSearchResultsEmpty = jest.fn();
       component.isArrowNavigationKey = jest.fn();
-      component.isEscapeKey = jest.fn();
       component.handleArrowNavigation = jest.fn();
       component.handleEscape = jest.fn();
     });
@@ -413,10 +414,12 @@ describe('InstantSearchComponent', () => {
         expect(component.isArrowNavigationKey).not.toHaveBeenCalled();
       });
 
-      it('should ignore escape key handling', () => {
-        component.onKeydownHandler(keyboardEvent);
+      it('should not handle escape key', () => {
+        component.handleEscape = jest.fn();
+
+        component.onKeydownHandler(createKeydownKeyboardEvent(ESCAPE_KEY));
 
-        expect(component.isEscapeKey).not.toHaveBeenCalled();
+        expect(component.handleEscape).not.toHaveBeenCalled();
       });
     });
 
@@ -452,24 +455,14 @@ describe('InstantSearchComponent', () => {
           component.isArrowNavigationKey = jest.fn().mockReturnValue(false);
         });
 
-        it('should check for escape key', () => {
-          component.onKeydownHandler(keyboardEvent);
-
-          expect(component.isEscapeKey).toHaveBeenCalled();
-        });
-
         it('should handle escape key', () => {
-          component.isEscapeKey = jest.fn().mockReturnValue(true);
-
-          component.onKeydownHandler(keyboardEvent);
+          component.onKeydownHandler(createKeydownKeyboardEvent(ESCAPE_KEY));
 
           expect(component.handleEscape).toHaveBeenCalled();
         });
 
         it('should not handle escape key', () => {
-          component.isEscapeKey = jest.fn().mockReturnValue(false);
-
-          component.onKeydownHandler(keyboardEvent);
+          component.onKeydownHandler(createKeydownKeyboardEvent(ENTER_KEY));
 
           expect(component.handleEscape).not.toHaveBeenCalled();
         });
@@ -511,22 +504,6 @@ describe('InstantSearchComponent', () => {
     });
   });
 
-  describe('isEscapeKey', () => {
-    it('should return true', () => {
-      const escapeKeyEvent = { ...new KeyboardEvent('esc'), key: 'Escape' };
-
-      const result: boolean = component.isEscapeKey(escapeKeyEvent);
-
-      expect(result).toBe(true);
-    });
-
-    it('should return false', () => {
-      const result: boolean = component.isEscapeKey(new KeyboardEvent('not escape'));
-
-      expect(result).toBe(false);
-    });
-  });
-
   describe('isLastItemOrOutOfArray', () => {
     it.each([3, 5])('should return true for %s', (index: number) => {
       const result: boolean = component.isLastItemOrOutOfArray(index, 4);
diff --git a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts
index 8b23822f25beea96c9bdf42a52c4eba075c50b9d..f62dc5c2d201e15a711aa8e7b6275275f1669755 100644
--- a/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts
+++ b/alfa-client/libs/design-system/src/lib/instant-search/instant-search/instant-search.component.ts
@@ -1,4 +1,10 @@
-import { EMPTY_STRING, isNotNil } from '@alfa-client/tech-shared';
+import {
+  EMPTY_STRING,
+  isArrowDownKey,
+  isArrowUpKey,
+  isEscapeKey,
+  isNotNil,
+} from '@alfa-client/tech-shared';
 import { CommonModule } from '@angular/common';
 import {
   Component,
@@ -118,7 +124,7 @@ export class InstantSearchComponent implements OnInit, OnDestroy {
   onKeydownHandler(e: KeyboardEvent): void {
     if (this.isSearchResultsEmpty()) return;
     if (this.isArrowNavigationKey(e)) this.handleArrowNavigation(e);
-    if (this.isEscapeKey(e)) this.handleEscape(e);
+    if (isEscapeKey(e)) this.handleEscape(e);
   }
 
   @HostListener('document:click', ['$event'])
@@ -209,11 +215,7 @@ export class InstantSearchComponent implements OnInit, OnDestroy {
   }
 
   isArrowNavigationKey(e: KeyboardEvent): boolean {
-    return e.key === 'ArrowDown' || e.key === 'ArrowUp';
-  }
-
-  isEscapeKey(e: KeyboardEvent): boolean {
-    return e.key === 'Escape';
+    return isArrowDownKey(e) || isArrowUpKey(e);
   }
 
   onItemClicked(searchResult: InstantSearchResult<Resource>, index: number): void {
diff --git a/alfa-client/libs/tech-shared/src/index.ts b/alfa-client/libs/tech-shared/src/index.ts
index 970130b8c3cc71fccd268eb842d34a249f578750..91817109a1f0fefeef0d83f63bc61c1422b9d3ca 100644
--- a/alfa-client/libs/tech-shared/src/index.ts
+++ b/alfa-client/libs/tech-shared/src/index.ts
@@ -29,6 +29,7 @@ export * from './lib/error/error.handler';
 export * from './lib/error/error.util';
 export * from './lib/form.util';
 export * from './lib/http.util';
+export * from './lib/keyboard.util';
 export * from './lib/message-code';
 export * from './lib/ngrx/actions';
 export * from './lib/pipe/convert-api-error-to-error-messages.pipe';
diff --git a/alfa-client/libs/tech-shared/src/lib/keyboard.util.spec.ts b/alfa-client/libs/tech-shared/src/lib/keyboard.util.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..641555ae216d025aced3cd4bd9150b349c391cfb
--- /dev/null
+++ b/alfa-client/libs/tech-shared/src/lib/keyboard.util.spec.ts
@@ -0,0 +1,67 @@
+import { createKeydownKeyboardEvent } from '../../../test-utils/src/lib/keyboard';
+import {
+  ARROW_DOWN_KEY,
+  ARROW_UP_KEY,
+  ENTER_KEY,
+  ESCAPE_KEY,
+  isArrowDownKey,
+  isArrowUpKey,
+  isEnterKey,
+  isEscapeKey,
+} from './keyboard.util';
+
+describe('keyboard', () => {
+  describe('isEscapeKey', () => {
+    it('should return true', () => {
+      const isEscape: boolean = isEscapeKey(createKeydownKeyboardEvent(ESCAPE_KEY));
+
+      expect(isEscape).toBeTruthy();
+    });
+
+    it('should return false', () => {
+      const isEscape: boolean = isEscapeKey(createKeydownKeyboardEvent(ENTER_KEY));
+
+      expect(isEscape).toBeFalsy();
+    });
+  });
+
+  describe('isEnterKey', () => {
+    it('should return true', () => {
+      const isEnter: boolean = isEnterKey(createKeydownKeyboardEvent(ENTER_KEY));
+
+      expect(isEnter).toBeTruthy();
+    });
+
+    it('should return false', () => {
+      const isEnter: boolean = isEnterKey(createKeydownKeyboardEvent(ESCAPE_KEY));
+
+      expect(isEnter).toBeFalsy();
+    });
+  });
+  describe('isArrowUpKey', () => {
+    it('should return true', () => {
+      const isArrowUp: boolean = isArrowUpKey(createKeydownKeyboardEvent(ARROW_UP_KEY));
+
+      expect(isArrowUp).toBeTruthy();
+    });
+
+    it('should return false', () => {
+      const isArrowUp: boolean = isArrowUpKey(createKeydownKeyboardEvent(ESCAPE_KEY));
+
+      expect(isArrowUp).toBeFalsy();
+    });
+  });
+  describe('isArrowDownKey', () => {
+    it('should return true', () => {
+      const isArrowDown: boolean = isArrowDownKey(createKeydownKeyboardEvent(ARROW_DOWN_KEY));
+
+      expect(isArrowDown).toBeTruthy();
+    });
+
+    it('should return false', () => {
+      const isEnter: boolean = isArrowDownKey(createKeydownKeyboardEvent(ESCAPE_KEY));
+
+      expect(isEnter).toBeFalsy();
+    });
+  });
+});
diff --git a/alfa-client/libs/tech-shared/src/lib/keyboard.util.ts b/alfa-client/libs/tech-shared/src/lib/keyboard.util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..879628cefa63b44b4408d7ac977ba29a8b9bdd39
--- /dev/null
+++ b/alfa-client/libs/tech-shared/src/lib/keyboard.util.ts
@@ -0,0 +1,20 @@
+export const ESCAPE_KEY = 'Escape';
+export const ENTER_KEY = 'Enter';
+export const ARROW_DOWN_KEY = 'ArrowDown';
+export const ARROW_UP_KEY = 'ArrowUp';
+
+export function isEscapeKey(keyboardEvent: KeyboardEvent) {
+  return keyboardEvent.key === ESCAPE_KEY;
+}
+
+export function isEnterKey(keyboardEvent: KeyboardEvent) {
+  return keyboardEvent.key === ENTER_KEY;
+}
+
+export function isArrowDownKey(keyboardEvent: KeyboardEvent) {
+  return keyboardEvent.key === ARROW_DOWN_KEY;
+}
+
+export function isArrowUpKey(keyboardEvent: KeyboardEvent) {
+  return keyboardEvent.key === ARROW_UP_KEY;
+}
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.util.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.util.spec.ts
index e5a9f28f281136f4ac735e04259cc76ce15a051e..b8d4d562732d4553910f3b0020c7f96377798179 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.util.spec.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.util.spec.ts
@@ -23,6 +23,7 @@
  */
 
 import { Resource } from '@ngxp/rest';
+import { createCommandStateResource } from '../../../../command-shared/test/command';
 import { DummyListLinkRel } from '../../../test/dummy';
 import { createApiError } from '../../../test/error';
 import { createDummyListResource, createDummyResource, toResource } from '../../../test/resource';
@@ -38,6 +39,7 @@ import {
   isInvalidResourceCombination,
   isLoaded,
   isLoadingRequired,
+  isNotLoading,
   isValidStateResource,
 } from './resource.util';
 
@@ -167,19 +169,13 @@ describe('resource util', () => {
 
   describe('containsLoading', () => {
     it('should return true', () => {
-      const contains = containsLoading([
-        createEmptyStateResource(true),
-        createEmptyStateResource(false),
-      ]);
+      const contains = containsLoading([createEmptyStateResource(true), createEmptyStateResource(false)]);
 
       expect(contains).toBeTruthy();
     });
 
     it('should return false', () => {
-      const contains = containsLoading([
-        createEmptyStateResource(false),
-        createEmptyStateResource(false),
-      ]);
+      const contains = containsLoading([createEmptyStateResource(false), createEmptyStateResource(false)]);
 
       expect(contains).toBeFalsy();
     });
@@ -193,10 +189,7 @@ describe('resource util', () => {
     });
 
     it('should return loaded', () => {
-      const loaded = getSuccessfullyLoaded([
-        createEmptyStateResource<Resource>(true),
-        loadedStateResource,
-      ]);
+      const loaded = getSuccessfullyLoaded([createEmptyStateResource<Resource>(true), loadedStateResource]);
 
       expect(loaded).toEqual([loadedStateResource]);
     });
@@ -230,10 +223,7 @@ describe('resource util', () => {
     it('should return true on loaded stateResource while configResource is null', () => {
       const stateResource: StateResource<Resource> = createStateResource(createDummyResource());
 
-      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(
-        stateResource,
-        null,
-      );
+      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(stateResource, null);
 
       expect(isInvalidCombination).toBeTruthy();
     });
@@ -242,10 +232,7 @@ describe('resource util', () => {
       const stateResource: StateResource<Resource> = createEmptyStateResource();
       const configResource: Resource = createDummyResource();
 
-      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(
-        stateResource,
-        configResource,
-      );
+      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(stateResource, configResource);
 
       expect(isInvalidCombination).toBeTruthy();
     });
@@ -257,10 +244,7 @@ describe('resource util', () => {
       };
       const configResource: Resource = createDummyResource();
 
-      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(
-        stateResource,
-        configResource,
-      );
+      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(stateResource, configResource);
 
       expect(isInvalidCombination).toBeFalsy();
     });
@@ -272,12 +256,29 @@ describe('resource util', () => {
       };
       const configResource: Resource = createDummyResource();
 
-      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(
-        stateResource,
-        configResource,
-      );
+      const isInvalidCombination: boolean = isInvalidResourceCombination<Resource, Resource>(stateResource, configResource);
 
       expect(isInvalidCombination).toBeTruthy();
     });
   });
+
+  describe('isNotLoading', () => {
+    it('should return true for empty state resource', () => {
+      const notLoading: boolean = isNotLoading(createEmptyStateResource());
+
+      expect(notLoading).toBeTruthy();
+    });
+
+    it('should return true', () => {
+      const notLoading: boolean = isNotLoading(createCommandStateResource());
+
+      expect(notLoading).toBeTruthy();
+    });
+
+    it('should return false', () => {
+      const notLoading: boolean = isNotLoading(createEmptyStateResource(true));
+
+      expect(notLoading).toBeFalsy();
+    });
+  });
 });
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.util.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.util.ts
index 4691f7998807aa6e0e35dbcea7d84a5fd4a09885..92900b7913c8f51f52166cbed03eeaf181557a06 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.util.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.util.ts
@@ -69,6 +69,10 @@ export function isLoaded<T>(stateResource: StateResource<T>): boolean {
   return !stateResource.loading && !stateResource.reload && isNotNull(stateResource.resource);
 }
 
+export function isNotLoading<T>(stateResource: StateResource<T>): boolean {
+  return !stateResource.loading;
+}
+
 export function hasStateResourceError(stateResource: StateResource<any>): boolean {
   return !isNil(stateResource.error);
 }
diff --git a/alfa-client/libs/test-utils/src/lib/dialog.ts b/alfa-client/libs/test-utils/src/lib/dialog.ts
index d9a32f03a17d554f48e5263d1df4c4b7bb552b9b..c882a2b8ca85ca7a09a87fb792aac41535b97249 100644
--- a/alfa-client/libs/test-utils/src/lib/dialog.ts
+++ b/alfa-client/libs/test-utils/src/lib/dialog.ts
@@ -1 +1,13 @@
-export const dialogRefMock = { close: jest.fn() };
+import { jest } from '@jest/globals';
+import { EMPTY, Observable } from 'rxjs';
+
+export class DialogRefMock<R = unknown> {
+  public keydownEvents: Observable<KeyboardEvent> = EMPTY;
+  public closed: Observable<R> = EMPTY;
+
+  public close = jest.fn();
+}
+
+export function createDialogRefMock<R = unknown>(): DialogRefMock<R> {
+  return new DialogRefMock();
+}
diff --git a/alfa-client/libs/test-utils/src/lib/helper.ts b/alfa-client/libs/test-utils/src/lib/helper.ts
index b95ce2e05c2a1912d502259ff1172ae34b16959b..95186d5b2b5cf003cbbb1a4cf33ec9388d1ebaa2 100644
--- a/alfa-client/libs/test-utils/src/lib/helper.ts
+++ b/alfa-client/libs/test-utils/src/lib/helper.ts
@@ -26,20 +26,22 @@ import { ComponentFixture } from '@angular/core/testing';
 import { By } from '@angular/platform-browser';
 import { EventData } from './model';
 
-export function getElementFromFixtureByType<T>(
-  fixture: ComponentFixture<any>,
-  component: Type<T>,
-): T {
+export function getElementFromFixtureByType<T>(fixture: ComponentFixture<any>, component: Type<T>): T {
   return getDebugElementFromFixtureByType(fixture, component).componentInstance as T;
 }
 
-function getDebugElementFromFixtureByType<T>(
-  fixture: ComponentFixture<any>,
-  component: Type<T>,
-): DebugElement {
+function getDebugElementFromFixtureByType<T>(fixture: ComponentFixture<any>, component: Type<T>): DebugElement {
   return fixture.debugElement.query(By.directive(component));
 }
 
+export function getElementsFromFixtureByType<T>(fixture: ComponentFixture<any>, component: Type<T>): T[] {
+  return getDebugElementsFromFixtureByType(fixture, component).map((element: DebugElement) => element.componentInstance as T);
+}
+
+function getDebugElementsFromFixtureByType<T>(fixture: ComponentFixture<any>, component: Type<T>): DebugElement[] {
+  return fixture.debugElement.queryAll(By.directive(component));
+}
+
 export function getElementFromFixture(fixture: ComponentFixture<any>, htmlElement: string): any {
   return fixture.nativeElement.querySelector(htmlElement);
 }
@@ -48,45 +50,33 @@ export function getElementsFromFixture(fixture: ComponentFixture<any>, htmlEleme
   return fixture.nativeElement.querySelectorAll(htmlElement);
 }
 
-export function dispatchEventFromFixture<T>(
-  fixture: ComponentFixture<T>,
-  elementSelector: string,
-  event: string,
-): void {
+export function dispatchEventFromFixture<T>(fixture: ComponentFixture<T>, elementSelector: string, event: string): void {
   const element: DebugElement = getDebugElementFromFixtureByCss(fixture, elementSelector);
   element.nativeElement.dispatchEvent(new Event(event));
 }
 
 export function triggerEvent<T>(eventData: EventData<T>) {
-  const element: DebugElement = getDebugElementFromFixtureByCss(
-    eventData.fixture,
-    eventData.elementSelector,
-  );
+  const element: DebugElement = getDebugElementFromFixtureByCss(eventData.fixture, eventData.elementSelector);
   element.triggerEventHandler(eventData.name, eventData.data);
 }
 
-export function getDebugElementFromFixtureByCss(
-  fixture: ComponentFixture<any>,
-  query: string,
-): DebugElement {
+export function getDebugElementFromFixtureByCss(fixture: ComponentFixture<any>, query: string): DebugElement {
   return fixture.debugElement.query(By.css(query));
 }
 
+export function getElementComponentFromFixtureByCss<T>(fixture: ComponentFixture<any>, query: string): T {
+  return fixture.debugElement.query(By.css(query)).componentInstance as T;
+}
+
 export function getElementFromDomRoot(fixture: ComponentFixture<any>, htmlElement: string): any {
   return fixture.nativeElement.parentNode.querySelector(htmlElement);
 }
 
-function getDebugElementFromFixtureByDirective(
-  fixture: ComponentFixture<any>,
-  query: Type<any>,
-): DebugElement {
+function getDebugElementFromFixtureByDirective(fixture: ComponentFixture<any>, query: Type<any>): DebugElement {
   return fixture.debugElement.query(By.directive(query));
 }
 
-function getAllDebugElementsFromFixtureByDirective(
-  fixture: ComponentFixture<any>,
-  query: Type<any>,
-): DebugElement[] {
+function getAllDebugElementsFromFixtureByDirective(fixture: ComponentFixture<any>, query: Type<any>): DebugElement[] {
   return fixture.debugElement.queryAll(By.directive(query));
 }
 
@@ -95,7 +85,5 @@ export function getMockComponent<T>(fixture: ComponentFixture<unknown>, componen
 }
 
 export function getMockComponents<T>(fixture: ComponentFixture<unknown>, component: Type<T>): T[] {
-  return getAllDebugElementsFromFixtureByDirective(fixture, component).map(
-    (debugElement) => <T>debugElement.componentInstance,
-  );
+  return getAllDebugElementsFromFixtureByDirective(fixture, component).map((debugElement) => <T>debugElement.componentInstance);
 }
diff --git a/alfa-client/libs/test-utils/src/lib/keyboard.ts b/alfa-client/libs/test-utils/src/lib/keyboard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8f53ef59ed1ce4dbbc6e03e35a18fd8b6432a948
--- /dev/null
+++ b/alfa-client/libs/test-utils/src/lib/keyboard.ts
@@ -0,0 +1,3 @@
+export function createKeydownKeyboardEvent(key: string): KeyboardEvent {
+  return new KeyboardEvent('keydown', { key });
+}
diff --git a/alfa-client/libs/test-utils/src/lib/observable.ts b/alfa-client/libs/test-utils/src/lib/observable.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8748d82162cb6e4bafce46984753a2674a810b98
--- /dev/null
+++ b/alfa-client/libs/test-utils/src/lib/observable.ts
@@ -0,0 +1,10 @@
+import { Mock, mock } from '@alfa-client/test-utils';
+import { Observable, Subscription } from 'rxjs';
+
+export function createSubscribedObservableMock<T>(): [Mock<Observable<T>>, Mock<Subscription>] {
+  const observableMock: Mock<Observable<T>> = mock(Observable<T>);
+  observableMock.pipe.mockReturnValue(observableMock);
+  const subscription: Mock<Subscription> = mock(Subscription);
+  observableMock.subscribe.mockReturnValue(subscription);
+  return [observableMock, subscription];
+}
diff --git a/alfa-client/libs/ui/src/index.ts b/alfa-client/libs/ui/src/index.ts
index ed84f3db5d20804637786f2d47d4e2ad8fed0f65..db9b583e4c67de83d5638cee0b66f31acbbb4720 100644
--- a/alfa-client/libs/ui/src/index.ts
+++ b/alfa-client/libs/ui/src/index.ts
@@ -50,6 +50,7 @@ export * from './lib/ui/open-url-button/open-url-button.component';
 export * from './lib/ui/ozgcloud-button/ozgcloud-button-with-spinner/ozgcloud-button-with-spinner.component';
 export * from './lib/ui/ozgcloud-button/ozgcloud-icon-button-primary/ozgcloud-icon-button-primary.component';
 export * from './lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component';
+export * from './lib/ui/ozgcloud-dialog/ozgcloud-dialog.result';
 export * from './lib/ui/ozgcloud-dialog/ozgcloud-dialog.service';
 export * from './lib/ui/ozgcloud-icon/ozgcloud-icon.component';
 export * from './lib/ui/ozgcloud-menu/ozgcloud-menu.component';
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result.spec.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c927d248d6c5de7a207ca6ea492905a8369246c1
--- /dev/null
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result.spec.ts
@@ -0,0 +1,82 @@
+import { createEmptyStateResource } from '@alfa-client/tech-shared';
+import { createSuccessfullyDoneCommandStateResource } from '../../../../../command-shared/test/command';
+import {
+  createDialogCancelResult,
+  createDialogResult,
+  isDialogCanceled,
+  isDialogSuccessfullyCompleted,
+  OzgcloudDialogCommandResult,
+} from './ozgcloud-dialog.result';
+
+describe('ozgcloud-dialog.result', () => {
+  describe('isDialogCanceled', () => {
+    it('should return true', () => {
+      const isDialogCancelled: boolean = isDialogCanceled({ stateResource: createEmptyStateResource() });
+
+      expect(isDialogCancelled).toBeTruthy();
+    });
+
+    it('should return false for null result', () => {
+      const isDialogCancelled: boolean = isDialogCanceled(null);
+
+      expect(isDialogCancelled).toBeFalsy();
+    });
+
+    it('should return false for null state resource', () => {
+      const isDialogCancelled: boolean = isDialogCanceled({ stateResource: null });
+
+      expect(isDialogCancelled).toBeFalsy();
+    });
+
+    it('should return false for non empty state resource', () => {
+      const isDialogCancelled: boolean = isDialogCanceled({ stateResource: createSuccessfullyDoneCommandStateResource() });
+
+      expect(isDialogCancelled).toBeFalsy();
+    });
+  });
+
+  describe('isDialogSuccessfullyCompleted', () => {
+    it('should return true', () => {
+      const isSuccessfullyCompleted: boolean = isDialogSuccessfullyCompleted({
+        stateResource: createSuccessfullyDoneCommandStateResource(),
+      });
+      expect(isSuccessfullyCompleted).toBeTruthy();
+    });
+
+    it('should return false for null result', () => {
+      const isSuccessfullyCompleted: boolean = isDialogSuccessfullyCompleted(null);
+
+      expect(isSuccessfullyCompleted).toBeFalsy();
+    });
+
+    it('should return false for null state resource', () => {
+      const isSuccessfullyCompleted: boolean = isDialogSuccessfullyCompleted({ stateResource: null });
+
+      expect(isSuccessfullyCompleted).toBeFalsy();
+    });
+
+    it('should return false for empty state resource', () => {
+      const isSuccessfullyCompleted: boolean = isDialogSuccessfullyCompleted({ stateResource: createEmptyStateResource() });
+
+      expect(isSuccessfullyCompleted).toBeFalsy();
+    });
+  });
+
+  describe('createDialogCancelResult', () => {
+    it('should create', () => {
+      const dialogResult: OzgcloudDialogCommandResult = createDialogCancelResult();
+
+      expect(dialogResult.stateResource).toEqual(createEmptyStateResource());
+    });
+  });
+
+  describe('createDialogResult', () => {
+    it('should create', () => {
+      const stateResource = createSuccessfullyDoneCommandStateResource();
+
+      const dialogCommandResult: OzgcloudDialogCommandResult = createDialogResult(stateResource);
+
+      expect(dialogCommandResult.stateResource).toBe(stateResource);
+    });
+  });
+});
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7404c7632d1965e81e92933aa4c68f18017cc1ad
--- /dev/null
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.result.ts
@@ -0,0 +1,29 @@
+import { CommandResource, isSuccessfulDone } from '@alfa-client/command-shared';
+import {
+  StateResource,
+  createEmptyStateResource,
+  isEmptyStateResource,
+} from '@alfa-client/tech-shared';
+
+export class OzgcloudDialogCommandResult<D = unknown> {
+  stateResource: StateResource<CommandResource>;
+  data?: D;
+}
+
+export function createDialogCancelResult(): OzgcloudDialogCommandResult {
+  return { stateResource: createEmptyStateResource() };
+}
+
+export function createDialogResult(
+  stateResource: StateResource<CommandResource>,
+): OzgcloudDialogCommandResult {
+  return { stateResource };
+}
+
+export function isDialogCanceled(dialogResult?: OzgcloudDialogCommandResult): boolean {
+  return dialogResult && isEmptyStateResource(dialogResult.stateResource);
+}
+
+export function isDialogSuccessfullyCompleted(dialogResult?: OzgcloudDialogCommandResult): boolean {
+  return dialogResult && isSuccessfulDone(dialogResult.stateResource?.resource);
+}
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts
index ca7bf24afd1e3f7fb1f4ba918cc6e3fe768aca33..61ff0c02a6c99af5ab62322705891bda9832e7d0 100644
--- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-dialog/ozgcloud-dialog.service.ts
@@ -20,11 +20,11 @@ export class OzgcloudDialogService {
 
   constructor(private dialog: Dialog) {}
 
-  public openWizard<T, D>(component: ComponentType<T>, data?: D): DialogRef<T> {
-    return this.openDialog<T>(component, this.buildDialogConfigWithData<D>(data, this.WIZARD_DIALOG_CONFIG));
+  public openWizard<C, D, R = unknown>(component: ComponentType<C>, data?: D): DialogRef<R> {
+    return this.openDialog<C, R>(component, this.buildDialogConfigWithData<D>(data, this.WIZARD_DIALOG_CONFIG));
   }
 
-  public open<T, D = unknown>(component: ComponentType<T>, data?: D): DialogRef<T> {
+  public open<C, D = unknown, R = unknown>(component: ComponentType<C>, data?: D): DialogRef<R> {
     return this.openDialog(component, this.buildDialogConfigWithData(data));
   }
 
@@ -36,13 +36,13 @@ export class OzgcloudDialogService {
     return this.openInCallingComponentContext(component, viewContainerRef, data, this.GREY_BLUR_CONFIG);
   }
 
-  public openInCallingComponentContext<T, D = unknown>(
-    component: ComponentType<T>,
+  public openInCallingComponentContext<C, D = unknown, R = unknown>(
+    component: ComponentType<C>,
     viewContainerRef: ViewContainerRef,
     data?: D,
     dialogConfig?: DialogConfig,
-  ): DialogRef<T> {
-    return this.openDialog(component, this.buildDialogConfigWithData(data, { viewContainerRef, ...dialogConfig }));
+  ): DialogRef<R> {
+    return this.openDialog<C, R>(component, this.buildDialogConfigWithData(data, { viewContainerRef, ...dialogConfig }));
   }
 
   private buildDialogConfigWithData<D>(data: D, dialogConfig?: DialogConfig): DialogConfig | null {
@@ -52,8 +52,8 @@ export class OzgcloudDialogService {
     return { ...dialogConfig, data };
   }
 
-  private openDialog<T>(component: ComponentType<T>, dialogConfig?: DialogConfig): DialogRef<T> {
-    return this.dialog.open<T>(component, dialogConfig);
+  private openDialog<C, R = unknown>(component: ComponentType<C>, dialogConfig?: DialogConfig): DialogRef<R, C> {
+    return this.dialog.open<R, unknown, C>(component, dialogConfig);
   }
 
   public closeAll(): void {
diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html
index 5cda3412cc39266c656446c0c2e2bfc65aadb80a..d4eaeaf311e5360232e193238680f26f75bfd36e 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html
+++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.html
@@ -30,7 +30,7 @@
     [text]="buttonText"
     svgIcon="stamp"
     [stateResource]="commandStateResource$ | async"
-    (clickEmitter)="onClick()"
+    (clickEmitter)="bescheiden()"
   >
   </ozgcloud-stroked-button-with-spinner>
 
@@ -40,7 +40,7 @@
     svgIcon="stamp"
     [toolTip]="toolTipText"
     [stateResource]="commandStateResource$ | async"
-    (clickEmitter)="onClick()"
+    (clickEmitter)="bescheiden()"
   >
   </ozgcloud-icon-button-with-spinner>
 </ng-container>
diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts
index d6251e13d63c817db05ef4b8a744e5d100d88b82..9e0cd75bc9717c51e9b1a2fb8012e3906008e769 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.spec.ts
@@ -21,22 +21,19 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared';
+import { BescheidResource, BescheidService, BescheidWizardDialogResult } from '@alfa-client/bescheid-shared';
 import { CommandResource } from '@alfa-client/command-shared';
-import {
-  HasLinkPipe,
-  StateResource,
-  createEmptyStateResource,
-  createStateResource,
-} from '@alfa-client/tech-shared';
-import { mock } from '@alfa-client/test-utils';
+import { createEmptyStateResource, createStateResource, HasLinkPipe, StateResource } from '@alfa-client/tech-shared';
+import { Mock, mock } from '@alfa-client/test-utils';
 import {
   IconButtonWithSpinnerComponent,
   OzgcloudDialogService,
   OzgcloudStrokedButtonWithSpinnerComponent,
 } from '@alfa-client/ui';
+import { BescheidenDialogData } from '@alfa-client/vorgang-detail';
 import {
   VorgangCommandService,
+  VorgangService,
   VorgangWithEingangLinkRel,
   VorgangWithEingangResource,
 } from '@alfa-client/vorgang-shared';
@@ -48,7 +45,6 @@ import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorga
 import { MockComponent } from 'ng-mocks';
 import { Observable, of } from 'rxjs';
 import { createBescheidResource } from '../../../../../bescheid-shared/src/test/bescheid';
-import { BescheidenDialogData } from '../../vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.model';
 import { VorgangDetailBescheidenComponent } from '../../vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component';
 import { BescheidenButtonComponent } from './bescheiden-button.component';
 
@@ -59,12 +55,20 @@ describe('BescheidenButtonComponent', () => {
   const bescheidenButton: string = getDataTestIdOf('bescheiden-button');
   const bescheidenIconButton: string = getDataTestIdOf('bescheiden-icon-button');
 
-  const vorgangCommandService = mock(VorgangCommandService);
-  const ozgcloudDialogService = mock(OzgcloudDialogService);
-  const bescheidService = mock(BescheidService);
+  let vorgangCommandService: Mock<VorgangCommandService>;
+  let ozgcloudDialogService: Mock<OzgcloudDialogService>;
+  let bescheidService: Mock<BescheidService>;
+  let vorgangService: Mock<VorgangService>;
 
   const dialogRef = <DialogRef<VorgangDetailBescheidenComponent>>{};
 
+  beforeEach(() => {
+    vorgangCommandService = mock(VorgangCommandService);
+    ozgcloudDialogService = mock(OzgcloudDialogService);
+    bescheidService = mock(BescheidService);
+    vorgangService = mock(VorgangService);
+  });
+
   beforeEach(async () => {
     await TestBed.configureTestingModule({
       declarations: [
@@ -86,6 +90,10 @@ describe('BescheidenButtonComponent', () => {
           provide: BescheidService,
           useValue: bescheidService,
         },
+        {
+          provide: VorgangService,
+          useValue: vorgangService,
+        },
       ],
     }).compileComponents();
 
@@ -172,23 +180,21 @@ describe('BescheidenButtonComponent', () => {
     });
   });
 
-  describe('onClick', () => {
+  describe('bescheiden', () => {
     describe('should open bescheid wizard', () => {
       beforeEach(() => {
         component.openBescheidenWizard = jest.fn();
-        component.vorgang = createVorgangWithEingangResource([
-          VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
-        ]);
+        component.vorgang = createVorgangWithEingangResource([VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT]);
       });
 
       it('should open bescheid wizard when create bescheid draft link exists', () => {
-        component.onClick();
+        component.bescheiden();
 
         expect(component.openBescheidenWizard).toHaveBeenCalled();
       });
 
       it('should open bescheid wizard when bescheid draft exists', () => {
-        component.onClick();
+        component.bescheiden();
 
         expect(component.openBescheidenWizard).toHaveBeenCalled();
       });
@@ -196,16 +202,14 @@ describe('BescheidenButtonComponent', () => {
 
     describe('should do bescheiden', () => {
       const command: CommandResource = createCommandResource();
-      const comandStateResource$: Observable<StateResource<CommandResource>> = of(
-        createStateResource(command),
-      );
+      const comandStateResource$: Observable<StateResource<CommandResource>> = of(createStateResource(command));
 
       beforeEach(() => {
         vorgangCommandService.bescheiden.mockReturnValue(comandStateResource$);
       });
 
       it('should call vorgangCommandService.bescheiden', () => {
-        component.onClick();
+        component.bescheiden();
 
         expect(vorgangCommandService.bescheiden).toHaveBeenCalled();
       });
@@ -213,7 +217,7 @@ describe('BescheidenButtonComponent', () => {
       it('should assign response', () => {
         component.commandStateResource$ = of(createEmptyStateResource<CommandResource>());
 
-        component.onClick();
+        component.bescheiden();
 
         expect(component.commandStateResource$).toBe(comandStateResource$);
       });
@@ -245,6 +249,37 @@ describe('BescheidenButtonComponent', () => {
     });
   });
 
+  // TODO: Use this version after completed Bescheid refactoring and delete the other version below.
+  // describe('openBescheidenWizard', () => {
+  //   let dialogRefMock: DialogRefMock<BescheidWizardDialogResult>;
+  //
+  //   beforeEach(() => {
+  //     dialogRefMock = createDialogRefMock<BescheidWizardDialogResult>();
+  //     ozgcloudDialogService.openWizard.mockReturnValue(dialogRefMock);
+  //   });
+  //
+  //   it('should open wizard dialog', () => {
+  //     const vorgang = createVorgangWithEingangResource();
+  //     component.vorgang = vorgang;
+  //
+  //     component.openBescheidenWizard();
+  //
+  //     expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith(BescheidWizardContainerComponent, {
+  //       vorgangWithEingangResource: vorgang,
+  //     });
+  //   });
+  //
+  //   it('should handleBescheidWizardClosed', () => {
+  //     component.handleBescheidWizardClosed = jest.fn();
+  //     const dialogResult: BescheidWizardDialogResult = { reloadVorgang: true };
+  //     dialogRefMock.closed = of(dialogResult);
+  //
+  //     component.openBescheidenWizard();
+  //
+  //     expect(component.handleBescheidWizardClosed).toHaveBeenCalledWith(dialogResult);
+  //   });
+  // });
+
   describe('openBescheidenWizard', () => {
     it('should init', () => {
       component.openBescheidenWizard();
@@ -253,9 +288,7 @@ describe('BescheidenButtonComponent', () => {
     });
 
     it('should open bescheiden dialog with existing draft', () => {
-      component.vorgang = createVorgangWithEingangResource([
-        VorgangWithEingangLinkRel.BESCHEID_DRAFT,
-      ]);
+      component.vorgang = createVorgangWithEingangResource([VorgangWithEingangLinkRel.BESCHEID_DRAFT]);
       component.openBescheidenDialogWithExistingDraft = jest.fn();
 
       component.openBescheidenWizard();
@@ -289,11 +322,10 @@ describe('BescheidenButtonComponent', () => {
 
   describe('openBescheidenDialogWithExistingDraft', () => {
     const bescheidDraftResource: BescheidResource = createBescheidResource();
-    const bescheidDraftStateResource: StateResource<BescheidResource> =
-      createStateResource(bescheidDraftResource);
-    const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(
-      [VorgangWithEingangLinkRel.BESCHEID_DRAFT],
-    );
+    const bescheidDraftStateResource: StateResource<BescheidResource> = createStateResource(bescheidDraftResource);
+    const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource([
+      VorgangWithEingangLinkRel.BESCHEID_DRAFT,
+    ]);
 
     beforeEach(() => {
       component.vorgang = vorgangWithEingangResource;
@@ -303,13 +335,10 @@ describe('BescheidenButtonComponent', () => {
     it('should open wizard if bescheid draft loaded', () => {
       component.openBescheidenDialogWithExistingDraft();
 
-      expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith(
-        VorgangDetailBescheidenComponent,
-        {
-          bescheidDraftResource,
-          vorgangWithEingangResource,
-        },
-      );
+      expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith(VorgangDetailBescheidenComponent, {
+        bescheidDraftResource,
+        vorgangWithEingangResource,
+      });
     });
 
     it('should not open wizard if bescheid draft not loaded', () => {
@@ -333,11 +362,10 @@ describe('BescheidenButtonComponent', () => {
 
   describe('openDialog', () => {
     const bescheidDraftResource: BescheidResource = createBescheidResource();
-    const bescheidDraftStateResource: StateResource<BescheidResource> =
-      createStateResource(bescheidDraftResource);
-    const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(
-      [VorgangWithEingangLinkRel.BESCHEID_DRAFT],
-    );
+    const bescheidDraftStateResource: StateResource<BescheidResource> = createStateResource(bescheidDraftResource);
+    const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource([
+      VorgangWithEingangLinkRel.BESCHEID_DRAFT,
+    ]);
 
     const dialogData: BescheidenDialogData = {
       bescheidDraftResource: bescheidDraftResource,
@@ -347,16 +375,32 @@ describe('BescheidenButtonComponent', () => {
     beforeEach(() => {
       component.vorgang = vorgangWithEingangResource;
       bescheidService.getBescheidDraftIfExists.mockReturnValue(of(bescheidDraftStateResource));
-      ozgcloudDialogService.openWizard;
     });
 
     it('should call ozgcloudDialogService.openWizard', () => {
       component.openDialog(dialogData);
 
-      expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith(
-        VorgangDetailBescheidenComponent,
-        dialogData,
-      );
+      expect(ozgcloudDialogService.openWizard).toHaveBeenCalledWith(VorgangDetailBescheidenComponent, dialogData);
+    });
+  });
+
+  describe('handleBescheidWizardClosed', () => {
+    it('should reload current vorgang', () => {
+      component.handleBescheidWizardClosed({ reloadVorgang: true });
+
+      expect(vorgangService.reloadCurrentVorgang).toHaveBeenCalled();
+    });
+
+    it('should not reload current vorgang', () => {
+      component.handleBescheidWizardClosed({ reloadVorgang: false });
+
+      expect(vorgangService.reloadCurrentVorgang).not.toHaveBeenCalled();
+    });
+
+    it.each([null, undefined])('should not reload current vorgang if result nil', (dialogResult: BescheidWizardDialogResult) => {
+      component.handleBescheidWizardClosed(dialogResult);
+
+      expect(vorgangService.reloadCurrentVorgang).not.toHaveBeenCalled();
     });
   });
 });
diff --git a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts
index d76a5cf53225299d7f63695281c06c13bba00cc0..09bc8b97ae156ce071a5f9bd72d497190a86b04e 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/buttons/bescheiden-button/bescheiden-button.component.ts
@@ -21,12 +21,13 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared';
+import { BescheidResource, BescheidService, BescheidWizardDialogResult } from '@alfa-client/bescheid-shared';
 import { CommandResource } from '@alfa-client/command-shared';
-import { StateResource, createEmptyStateResource, isLoaded } from '@alfa-client/tech-shared';
+import { StateResource, createEmptyStateResource, isLoaded, isNotNil } from '@alfa-client/tech-shared';
 import { OzgcloudDialogService } from '@alfa-client/ui';
 import {
   VorgangCommandService,
+  VorgangService,
   VorgangWithEingangLinkRel,
   VorgangWithEingangResource,
 } from '@alfa-client/vorgang-shared';
@@ -45,25 +46,23 @@ export class BescheidenButtonComponent implements OnInit {
   @Input() vorgang: VorgangWithEingangResource;
   @Input() showAsIconButton: boolean = false;
 
-  commandStateResource$: Observable<StateResource<CommandResource>> = of(
-    createEmptyStateResource<CommandResource>(),
-  );
+  commandStateResource$: Observable<StateResource<CommandResource>> = of(createEmptyStateResource<CommandResource>());
 
   readonly linkRel = VorgangWithEingangLinkRel;
 
   get buttonText(): string {
-    return hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT) ? 'Bescheiden fortsetzen'
-      : 'Bescheiden';
+    return hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT) ? 'Bescheiden fortsetzen' : 'Bescheiden';
   }
 
   get toolTipText(): string {
-    return hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT) ?
-        'Vorgang bescheiden fortsetzen'
-      : 'Vorgang bescheiden';
+    return hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT) ? 'Vorgang bescheiden fortsetzen' : (
+        'Vorgang bescheiden'
+      );
   }
 
   constructor(
     private vorgangCommandService: VorgangCommandService,
+    private vorgangService: VorgangService,
     private ozgcloudDialogService: OzgcloudDialogService,
     private bescheidService: BescheidService,
   ) {}
@@ -72,7 +71,7 @@ export class BescheidenButtonComponent implements OnInit {
     this.commandStateResource$ = this.vorgangCommandService.getBeschiedenCommand();
   }
 
-  public onClick(): void {
+  public bescheiden(): void {
     if (this.shouldOpenBescheidenWizard()) {
       this.openBescheidenWizard();
     } else {
@@ -87,6 +86,23 @@ export class BescheidenButtonComponent implements OnInit {
     );
   }
 
+  // TODO: Use this version after completed Bescheid refactoring and delete the other version below.
+  // public openBescheidenWizard(): void {
+  //   const dialogData: BescheidenDialogData = { vorgangWithEingangResource: this.vorgang };
+  //   const dialogRef: DialogRef<BescheidWizardDialogResult> = this.ozgcloudDialogService.openWizard<
+  //     BescheidWizardContainerComponent,
+  //     BescheidenDialogData,
+  //     BescheidWizardDialogResult
+  //   >(BescheidWizardContainerComponent, dialogData);
+  //   dialogRef.closed.subscribe((dialogResult: BescheidWizardDialogResult) => this.handleBescheidWizardClosed(dialogResult));
+  // }
+
+  handleBescheidWizardClosed(dialogResult: BescheidWizardDialogResult): void {
+    if (isNotNil(dialogResult) && dialogResult.reloadVorgang) {
+      this.vorgangService.reloadCurrentVorgang();
+    }
+  }
+
   public openBescheidenWizard(): void {
     this.bescheidService.init();
     if (hasLink(this.vorgang, VorgangWithEingangLinkRel.BESCHEID_DRAFT)) {
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts
index a88075f699841c8e2b5d9c085023f6f087efc854..4aa88c6ad462e183f3e7e626034f402eb4d506e4 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden.component.ts
@@ -1,5 +1,6 @@
 import { BescheidResource } from '@alfa-client/bescheid-shared';
 import { PostfachService } from '@alfa-client/postfach-shared';
+import { isEscapeKey } from '@alfa-client/tech-shared';
 import { OzgcloudDialogService } from '@alfa-client/ui';
 import { VorgangService } from '@alfa-client/vorgang-shared';
 import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
@@ -41,7 +42,7 @@ export class VorgangDetailBescheidenComponent implements OnDestroy, OnInit {
 
   handleEscapeKey(): void {
     this.keydownEventsSubscription = this.dialogRef.keydownEvents
-      .pipe(filter((event) => event.key === 'Escape'))
+      .pipe(filter(isEscapeKey))
       .subscribe(() => this.cancelWizard());
   }
 
diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts
index adb12daf7e4ec5b14e8c3e505413869531193abb..a08b21697fa35477ad73dfcfef9456028c33f6a5 100644
--- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts
+++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-dialog.component.spec.ts
@@ -1,5 +1,13 @@
 import { ToEmbeddedResourcesPipe } from '@alfa-client/tech-shared';
-import { EventData, Mock, dialogRefMock, getMockComponent, mock, triggerEvent } from '@alfa-client/test-utils';
+import {
+  createDialogRefMock,
+  DialogRefMock,
+  EventData,
+  getMockComponent,
+  Mock,
+  mock,
+  triggerEvent,
+} from '@alfa-client/test-utils';
 import {
   OrganisationsEinheitResource,
   OrganisationsEinheitService,
@@ -27,8 +35,14 @@ describe('SearchZustaendigeStelleDialogComponent', () => {
   const service: Mock<OrganisationsEinheitService> = mock(OrganisationsEinheitService);
   const title: string = 'dummyTitle';
 
+  let dialogRefMock: DialogRefMock;
+
   const organisationsEinheitResource: OrganisationsEinheitResource = createOrganisationsEinheitResource();
 
+  beforeEach(() => {
+    dialogRefMock = createDialogRefMock();
+  });
+
   beforeEach(async () => {
     await TestBed.configureTestingModule({
       declarations: [