From b9f8ba6b905cdf8d9d847bd231dba30e9d6ac29d Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Wed, 26 Mar 2025 18:45:56 +0100
Subject: [PATCH 1/8] OZG-7872 use state vorgang directly on change listener
 (avoiding useless reloading)

---
 .../libs/kommentar-shared/src/lib/kommentar.service.spec.ts     | 2 +-
 alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts  | 2 +-
 .../libs/postfach-shared/src/lib/postfach.service.spec.ts       | 2 +-
 alfa-client/libs/postfach-shared/src/lib/postfach.service.ts    | 2 +-
 .../wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts  | 2 +-
 .../libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts  | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts
index 5860d36428..bd09cc77d8 100644
--- a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts
+++ b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts
@@ -461,7 +461,7 @@ describe('KommentarService', () => {
     it('should call vorgang service to get vorgang with eingang', () => {
       service._listenToVorgangChange();
 
-      expect(vorgangService.getVorgangWithEingang).toHaveBeenCalled();
+      expect(vorgangService.selectVorgangWithEingang).toHaveBeenCalled();
     });
 
     it('should call handle vorgang change', () => {
diff --git a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts
index 395872897b..876f32e5af 100644
--- a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts
+++ b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.ts
@@ -107,7 +107,7 @@ export class KommentarService {
 
   _listenToVorgangChange(): void {
     this.vorgangSubscription = this.vorgangService
-      .getVorgangWithEingang()
+      .selectVorgangWithEingang()
       .subscribe((vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>) =>
         this._handleVorgangChange(vorgangWithEingangStateResource),
       );
diff --git a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
index 9149471c8d..876e08a03d 100644
--- a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
+++ b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
@@ -582,7 +582,7 @@ describe('PostfachService', () => {
     it('should call vorgang service to get vorgang with eingang', () => {
       service._listenToVorgangChange();
 
-      expect(vorgangService.getVorgangWithEingang).toHaveBeenCalled();
+      expect(vorgangService.selectVorgangWithEingang).toHaveBeenCalled();
     });
 
     it('should call handle vorgang change', () => {
diff --git a/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts b/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts
index f650edd3f4..b7fbfbe62d 100644
--- a/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts
+++ b/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts
@@ -292,7 +292,7 @@ export class PostfachService {
 
   _listenToVorgangChange(): void {
     this.vorgangChangeSubscription = this.vorgangService
-      .getVorgangWithEingang()
+      .selectVorgangWithEingang()
       .subscribe((vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>) =>
         this._handleVorgangChange(vorgangWithEingangStateResource),
       );
diff --git a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
index 13e5fcd714..f2513adc3b 100644
--- a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
+++ b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
@@ -583,7 +583,7 @@ describe('WiedervorlageService', () => {
     it('should call vorgang service to get vorgang with eingang', () => {
       service._listenToVorgangChange();
 
-      expect(vorgangService.getVorgangWithEingang).toHaveBeenCalled();
+      expect(vorgangService.selectVorgangWithEingang).toHaveBeenCalled();
     });
 
     it('should call handle vorgang change', () => {
diff --git a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts
index 6590ff6738..ad5e3f9ea1 100644
--- a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts
+++ b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts
@@ -122,7 +122,7 @@ export class WiedervorlageService implements OnDestroy {
 
   _listenToVorgangChange(): void {
     this.vorgangSubscription = this.vorgangService
-      .getVorgangWithEingang()
+      .selectVorgangWithEingang()
       .subscribe((vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource>) =>
         this._handleVorgangChange(vorgangWithEingangStateResource),
       );
-- 
GitLab


From 80320525d5d8a10901e28939e9c970db8dcd0056 Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Mon, 31 Mar 2025 23:51:41 +0200
Subject: [PATCH 2/8] OZG-7872 OZG-8041 add e2e test for pending send postfach
 command

---
 .../postfach/postfach-mail.e2e.component.ts   | 107 +++++++++---------
 .../vorgang-detail/vorgang-forwarding.cy.ts   |   2 +-
 .../postfach-mail/postfach-mail-error.cy.ts   |  77 ++++++-------
 .../postfach-mail/postfach-mail.cy.ts         |  23 ++--
 ...ail.filtered-by-organisationseinheit.cy.ts |  11 +-
 ...postfach-nachricht-authorize-by-role.cy.ts |  25 +---
 .../postfach-nachricht-pending-send.cy.ts     |  67 +++++++++++
 .../postfach-nachricht-reply-button.cy.ts     |   9 +-
 .../postfach-mail/postfach-nachrichten.cy.ts  |  11 +-
 .../vorgang-forwarding.cy.ts                  |   2 +-
 .../src/fixtures/command/command.json         |   7 +-
 .../postfach/send-postfach-nachricht.json     |  23 ++++
 .../usermanager/usermanager_user_ludwig.json  |  18 +++
 .../usermanager/usermanager_user_zonk.json    |  18 +++
 .../helper/forwarding/forwarding.navigator.ts |   2 +-
 .../postfach-nachricht.navigator.ts           |   9 ++
 .../postfach-nachricht.verifier.ts            |  27 +++++
 .../src/helper/vorgang/vorgang.navigator.ts   |  10 +-
 .../apps/alfa-e2e/src/model/command.ts        |  11 +-
 .../apps/alfa-e2e/src/page-objects/main.po.ts |  18 ++-
 .../postfach-mail.component.po.ts             |   6 +-
 .../alfa-e2e/src/support/cypress-helper.ts    |   4 +
 .../alfa-e2e/src/support/cypress-tasks.ts     |  25 ++--
 alfa-client/apps/alfa-e2e/src/support/e2e.ts  |   7 ++
 .../src/support/postfach-nachricht.util.ts    |   6 +
 .../postfach-mail-button.component.html       |   1 -
 .../incomming-mail.component.html             |   8 +-
 .../incomming-mail.component.spec.ts          |   4 +-
 ...tgoing-mail-error-container.component.html |   2 +-
 ...ing-mail-error-container.component.spec.ts |  57 ++++++----
 ...outgoing-mail-error-container.component.ts |  25 ++--
 .../outgoing-mail-error.component.html        |  14 +--
 .../outgoing-mail.component.html              |  10 +-
 .../outgoing-mail.component.spec.ts           |   8 +-
 .../postfach-mail-date.component.html         |   4 +-
 .../postfach-mail-date.component.spec.ts      |   5 +-
 ...stroked-button-with-spinner.component.html |   1 +
 ...d-stroked-button-with-spinner.component.ts |   1 +
 38 files changed, 410 insertions(+), 255 deletions(-)
 create mode 100644 alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts
 create mode 100644 alfa-client/apps/alfa-e2e/src/fixtures/postfach/send-postfach-nachricht.json
 create mode 100644 alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ludwig.json
 create mode 100644 alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zonk.json
 create mode 100644 alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.navigator.ts
 create mode 100644 alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.verifier.ts

diff --git a/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail.e2e.component.ts
index 1bb7839d10..30a485fc0e 100644
--- a/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail.e2e.component.ts
+++ b/alfa-client/apps/alfa-e2e/src/components/postfach/postfach-mail.e2e.component.ts
@@ -21,6 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { getTestElement } from '../../support/cypress-helper';
 import { convertToDataTestId } from '../../support/tech.util';
 import { AttachmentContainerE2EComponent } from '../attachment/attachment.e2e.component';
 import { UserProfileE2EComponent } from '../user-profile/user-profile.component.e2e';
@@ -36,103 +37,105 @@ export class PostfachMailE2EComponent {
 
   private readonly locatorRoot: string = 'postfach-nachrichten-container-in-vorgang';
 
-  public getRoot() {
-    return cy.getTestElement(this.locatorRoot);
+  public getRoot(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.locatorRoot);
   }
 
-  public getCreateButtonWithText() {
-    return cy.getTestElement(this.createMailButtonWithText);
+  public getCreateButtonWithText(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.createMailButtonWithText);
   }
 
-  public getCreateButtonWithoutText() {
-    return cy.getTestElement(this.createMailButtonWithoutText);
+  public getCreateButtonWithoutText(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.createMailButtonWithoutText);
   }
 
-  public getList() {
-    return cy.getTestElement(this.list);
+  public getList(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.list);
   }
 
-  public getNoPostfachText() {
-    return cy.getTestElement(this.noPostfachText);
+  public getNoPostfachText(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.noPostfachText);
   }
 
-  public getListItem(subject: string): PostfachMailListItem {
-    return new PostfachMailListItem(subject);
+  public getListItem(subject: string): PostfachMailListItemE2EComponent {
+    return new PostfachMailListItemE2EComponent(subject);
   }
 
-  public getAttachments() {
-    return cy.getTestElement(this.attachments);
+  public getAttachments(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.attachments);
   }
 
-  public getDownloadButtonWithIcon() {
-    return cy.getTestElement(this.downloadButtonWithIcon);
+  public getDownloadButtonWithIcon(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.downloadButtonWithIcon);
   }
 
-  public getDownloadButtonWithLabel() {
-    return cy.getTestElement(this.downloadButtonWithLabel);
+  public getDownloadButtonWithLabel(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.downloadButtonWithLabel);
   }
 }
 
-export class PostfachMailListItem {
-  //TODO: Rename -> PostfachMailListItemE2EComponent
+export class PostfachMailListItemE2EComponent {
+  private readonly createdAt: string = 'mail-created-at';
+  private readonly subject: string = 'mail-subject';
+  private readonly text: string = 'mail-text';
+  private readonly replyIcon: string = 'reply-icon';
+  private readonly sentAt: string = 'mail-sent-at';
+  private readonly editButton: string = 'postfach-nachricht-edit-button-container';
 
-  private readonly locatorCreatedAt: string = 'mail-created-at';
-  private readonly locatorSubject: string = 'mail-subject';
-  private readonly locatorText: string = 'mail-text';
-  private readonly locatorReplyIcon: string = 'reply-icon';
-  private readonly locatorSentAt: string = 'mail-sent-at';
+  private readonly sendErrorText: string = 'mail-send-error-text';
+  private readonly sendErrorIcon: string = 'mail-send-error-icon';
+  private readonly resendButton: string = 'resend-nachricht-button';
 
-  private readonly locatorMailSendErrorText: string = 'mail-send-error-text';
-  private readonly locatorMailSendErrorIcon: string = 'mail-send-error-icon';
-  private readonly locatorMailResendButton: string = 'mail-resend-button';
+  private readonly attachmentContainer: AttachmentContainerE2EComponent = new AttachmentContainerE2EComponent();
 
-  private readonly attachmentContainer: AttachmentContainerE2EComponent =
-    new AttachmentContainerE2EComponent();
-
-  private locatorRoot: string;
+  private root: string;
 
   constructor(subject: string) {
-    this.locatorRoot = convertToDataTestId(subject) + '-item';
+    this.root = convertToDataTestId(subject) + '-item';
+  }
+
+  public getRoot(): Cypress.Chainable<JQuery<Element>> {
+    return getTestElement(this.root);
   }
 
-  public getRoot() {
-    return cy.getTestElement(this.locatorRoot);
+  public getEditButton(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.editButton);
   }
 
-  public getSubject() {
-    return this.getRoot().getTestElement(this.locatorSubject);
+  public getSubject(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.subject);
   }
 
-  public getText() {
-    return this.getRoot().getTestElement(this.locatorText);
+  public getText(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.text);
   }
 
-  public getCreatedAt() {
-    return this.getRoot().getTestElement(this.locatorCreatedAt);
+  public getCreatedAt(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.createdAt);
   }
 
   public getUserProfile(): UserProfileE2EComponent {
-    return new UserProfileE2EComponent(this.locatorRoot);
+    return new UserProfileE2EComponent(this.root);
   }
 
-  public getReplyIcon() {
-    return this.getRoot().getTestElement(this.locatorReplyIcon);
+  public getReplyIcon(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.replyIcon);
   }
 
-  public getSentAt() {
-    return this.getRoot().getTestElement(this.locatorSentAt);
+  public getSentAt(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.sentAt);
   }
 
-  public getMailSendErrorText() {
-    return this.getRoot().getTestElement(this.locatorMailSendErrorText);
+  public getSendErrorText(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.sendErrorText);
   }
 
-  public getMailSendErrorIcon() {
-    return this.getRoot().getTestElement(this.locatorMailSendErrorIcon);
+  public getSendErrorIcon(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.sendErrorIcon);
   }
 
-  public getResendButton() {
-    return this.getRoot().getTestElement(this.locatorMailResendButton);
+  public getResendButton(): Cypress.Chainable<JQuery<Element>> {
+    return this.getRoot().findTestElementWithClass(this.resendButton);
   }
 
   public getAttachmentContainer(): AttachmentContainerE2EComponent {
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding.cy.ts
index 82dd57a8ae..0a80fc4dc8 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/einheitlicher-ansprechpartner/vorgang-detail/vorgang-forwarding.cy.ts
@@ -31,7 +31,7 @@ describe('Vorgang weiterleiten innerhalb der OzgCloud', () => {
       });
 
       it('should open vorgang', () => {
-        vorgangNavigator.openVorgangDetailByName(vorgangWeiterleiten.name);
+        vorgangNavigator.openVorgang(vorgangWeiterleiten.name);
       });
 
       it('should display Weiterleiten button in Status Neu', () => {
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts
index 14814f7d70..7248a1727b 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts
@@ -21,35 +21,40 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { E2EAppHelper } from 'apps/alfa-e2e/src/helper/app.helper';
+import { E2EPostfachNachrichtVerifier } from 'apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.verifier';
+import { E2EVorgangNavigator } from 'apps/alfa-e2e/src/helper/vorgang/vorgang.navigator';
 import {
   createPostfachNachrichtAttachedItem,
   createPostfachNachrichtReplyItem,
 } from 'apps/alfa-e2e/src/support/postfach-nachricht.util';
-import { PostfachMailE2EComponent, PostfachMailListItem } from '../../../components/postfach/postfach-mail.e2e.component';
+import {
+  PostfachMailE2EComponent,
+  PostfachMailListItemE2EComponent,
+} from '../../../components/postfach/postfach-mail.e2e.component';
 import { SnackBarE2EComponent } from '../../../components/ui/snackbar.e2e.component';
-import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component';
 import { VorgangSubnavigationE2EComponent } from '../../../components/vorgang/vorgang-subnavigation';
 import { VorgangE2E } from '../../../model/vorgang';
 import {
   DirectionE2E,
   PostfachMailItemE2E,
   PostfachNachrichtMessageCodeE2E,
-  PostfachNachrichtMessageCodeMessagesE2E,
   PostfachNachrichtSnackbarMessageE2E,
   VorgangAttachedItemE2E,
 } from '../../../model/vorgang-attached-item';
-import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
+import { containsSpinner, MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
 import { PostfachMailPage } from '../../../page-objects/postfach-mail.component.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
-import { dropCollections } from '../../../support/cypress-helper';
 import { contains, exist, notExist } from '../../../support/cypress.util';
-import { getUserSabineId, loginAsSabine } from '../../../support/user-util';
+import { getUserSabineId } from '../../../support/user-util';
 import { initVorgangAttachedItem } from '../../../support/vorgang-attached-item-util';
 import { createVorgang, initVorgang, objectIds } from '../../../support/vorgang-util';
 
 describe('PostfachMail error', () => {
+  const appHelper: E2EAppHelper = new E2EAppHelper();
+  const vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator();
+
   const mainPage: MainPage = new MainPage();
-  const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList();
   const snackbar: SnackBarE2EComponent = mainPage.getSnackBar();
 
   const vorgangPage: VorgangPage = new VorgangPage();
@@ -58,9 +63,12 @@ describe('PostfachMail error', () => {
 
   const postfachMailPage: PostfachMailPage = new PostfachMailPage();
 
+  const verifier: E2EPostfachNachrichtVerifier = new E2EPostfachNachrichtVerifier();
+
   const vorgang: VorgangE2E = createVorgang();
   const postfachMailItem: PostfachMailItemE2E = {
     ...createPostfachNachrichtReplyItem(),
+    subject: 'Failed Outgoing Postfach Nachricht 1',
     createdBy: getUserSabineId(),
     direction: DirectionE2E.OUT,
     sentAt: '2022-12-02T15:00:00.790Z[UTC]',
@@ -73,26 +81,26 @@ describe('PostfachMail error', () => {
     item: postfachMailItem,
   };
 
+  const postfachNachricht2: PostfachMailItemE2E = {
+    ...postfachMailItem,
+    subject: 'Failed Outgoing Postfach Nachricht 2',
+  };
+  const vorgangAttachedItem2: VorgangAttachedItemE2E = {
+    ...createPostfachNachrichtAttachedItem(objectIds[1], vorgang._id.$oid),
+    item: postfachNachricht2,
+  };
+
   before(() => {
     initVorgang(vorgang);
-    initVorgangAttachedItem([vorgangAttachedItem]);
+    initVorgangAttachedItem([vorgangAttachedItem, vorgangAttachedItem2]);
 
-    loginAsSabine();
-
-    waitForSpinnerToDisappear();
-    exist(vorgangList.getRoot());
-  });
-
-  after(() => {
-    dropCollections();
+    appHelper.loginAsSabine();
   });
 
   describe('navigate to vorgang detail', () => {
     it('should open vorgang detail', () => {
-      vorgangList.getListItem(vorgang.name).getRoot().click();
+      vorgangNavigator.openVorgang(vorgang.name);
       waitForSpinnerToDisappear();
-
-      exist(vorgangPage.getVorgangDetailHeader().getRoot());
     });
 
     it('should show postfach mail button', () => {
@@ -109,44 +117,23 @@ describe('PostfachMail error', () => {
   });
 
   describe('postfach mail list', () => {
-    let listItem: PostfachMailListItem;
+    let listItem: PostfachMailListItemE2EComponent;
 
     beforeEach(() => {
       listItem = postfachMailPage.getListItem(postfachMailItem.subject);
     });
 
-    describe('contains failed sent mail item', () => {
-      it('should show mail subject', () => {
-        contains(listItem.getSubject(), postfachMailItem.subject);
-      });
-
-      it('should show user profile', () => {
-        exist(listItem.getUserProfile().getRoot());
-      });
-
-      it('should show sent date', () => {
-        exist(listItem.getSentAt());
-      });
-
-      it('should show text', () => {
-        contains(listItem.getMailSendErrorText(), PostfachNachrichtMessageCodeMessagesE2E.PROCESSING_FAILED);
-      });
-
-      it('should show error message', () => {
-        exist(listItem.getMailSendErrorIcon());
-      });
-
-      it('should show button', () => {
-        exist(listItem.getResendButton());
-      });
+    it('should contains failed postfach nachricht item', () => {
+      verifier.verifyFailedItemInList(postfachMailItem.subject);
     });
 
     describe('resend mail', () => {
       it('click on resend button should hide error', () => {
         listItem.getResendButton().click();
+        containsSpinner(listItem.getResendButton());
         waitForSpinnerToDisappear();
 
-        notExist(listItem.getMailSendErrorIcon());
+        notExist(listItem.getSendErrorIcon());
       });
 
       describe('resend mail item', () => {
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts
index f818bb1783..6a33ba8948 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.cy.ts
@@ -34,7 +34,10 @@ import {
   createPostfachNachrichtReplyItem,
 } from 'apps/alfa-e2e/src/support/postfach-nachricht.util';
 import { PostfachMailFormularE2EComponent } from '../../../components/postfach/postfach-mail-formular.e2e.component';
-import { PostfachMailE2EComponent, PostfachMailListItem } from '../../../components/postfach/postfach-mail.e2e.component';
+import {
+  PostfachMailE2EComponent,
+  PostfachMailListItemE2EComponent,
+} from '../../../components/postfach/postfach-mail.e2e.component';
 import { FixedDialogE2EComponent } from '../../../components/ui/fixed-dialog.e2e.component';
 import { SnackBarE2EComponent } from '../../../components/ui/snackbar.e2e.component';
 import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component';
@@ -50,7 +53,7 @@ import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.
 import { PostfachMailPage } from '../../../page-objects/postfach-mail.component.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
 import { expectIconWithBadge, expectIconWithoutBadge } from '../../../support/angular.util';
-import { dropCollections, readFileFromDownloads } from '../../../support/cypress-helper';
+import { readFileFromDownloads } from '../../../support/cypress-helper';
 import { beChecked, contains, exist, notBeChecked, notBeVisible, notExist, visible } from '../../../support/cypress.util';
 import { TEST_FILE_WITH_CONTENT, TEST_FILE_WITH_CONTENT_4_MB, TEST_FILE_WITHOUT_CONTENT } from '../../../support/data.util';
 import { initUsermanagerUsers, loginAsSabine } from '../../../support/user-util';
@@ -122,10 +125,6 @@ describe('PostfachMail', () => {
     exist(vorgangList.getRoot());
   });
 
-  after(() => {
-    dropCollections();
-  });
-
   describe('mail icon', () => {
     it('should not be visible', () => {
       notExist(vorgangList.getListItem(vorgang.name).getPostfachIcon());
@@ -328,7 +327,7 @@ describe('PostfachMail', () => {
       });
 
       it('should show postfach mail in list', () => {
-        const postfachMailItem: PostfachMailListItem = postfachMailContainer.getListItem(postfachMailToSend.subject);
+        const postfachMailItem: PostfachMailListItemE2EComponent = postfachMailContainer.getListItem(postfachMailToSend.subject);
 
         exist(postfachMailItem.getRoot());
         exist(postfachMailItem.getUserProfile().getRoot());
@@ -340,7 +339,7 @@ describe('PostfachMail', () => {
 
     describe('click on postfach mail item with attachment', () => {
       it('should show postfach item list', () => {
-        const postfachMailItem: PostfachMailListItem = postfachMailContainer.getListItem(postfachMailToSend.subject);
+        const postfachMailItem: PostfachMailListItemE2EComponent = postfachMailContainer.getListItem(postfachMailToSend.subject);
         postfachMailItem.getRoot().click();
         waitForSpinnerToDisappear();
 
@@ -348,13 +347,13 @@ describe('PostfachMail', () => {
       });
 
       it('should contain mail item with attachment', () => {
-        const postfachListItem: PostfachMailListItem = postfachMailPage.getListItem(postfachMailToSend.subject);
+        const postfachListItem: PostfachMailListItemE2EComponent = postfachMailPage.getListItem(postfachMailToSend.subject);
 
         exist(postfachListItem.getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getRoot());
       });
 
       it('should download attachment after click', () => {
-        const postfachListItem: PostfachMailListItem = postfachMailPage.getListItem(postfachMailToSend.subject);
+        const postfachListItem: PostfachMailListItemE2EComponent = postfachMailPage.getListItem(postfachMailToSend.subject);
 
         postfachListItem.getAttachmentContainer().getList().getItem(TEST_FILE_WITH_CONTENT).getDownloadButton().click();
         waitForSpinnerToDisappear();
@@ -363,7 +362,7 @@ describe('PostfachMail', () => {
       });
 
       it('should not contain failed upload', () => {
-        const postfachListItem: PostfachMailListItem = postfachMailPage.getListItem(postfachMailToSend.subject);
+        const postfachListItem: PostfachMailListItemE2EComponent = postfachMailPage.getListItem(postfachMailToSend.subject);
 
         notExist(
           postfachListItem.getAttachmentContainer().getList().getLoadingOrErrorItem(TEST_FILE_WITH_CONTENT_4_MB).getRoot(),
@@ -461,7 +460,7 @@ describe('PostfachMail', () => {
   });
 
   describe('click on postfach mail item', () => {
-    let postfachMailReplyItem: PostfachMailListItem;
+    let postfachMailReplyItem: PostfachMailListItemE2EComponent;
 
     beforeEach(() => {
       postfachMailReplyItem = postfachMailPage.getListItem(postfachMailReply.subject);
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.cy.ts
index bb94de6b4b..7c15088c5a 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail.filtered-by-organisationseinheit.cy.ts
@@ -27,12 +27,9 @@ import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-lis
 import { EingangE2E, VorgangE2E } from '../../../model/vorgang';
 import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
 import { PostfachMailPage } from '../../../page-objects/postfach-mail.component.po';
-import { dropCollections, visitUrl } from '../../../support/cypress-helper';
+import { visitUrl } from '../../../support/cypress-helper';
 import { contains, exist, notExist } from '../../../support/cypress.util';
-import {
-  ORGANISATIONSEINHEITEN_ID_FOR_ADELHEIT,
-  ORGANISATIONSEINHEITEN_ID_FOR_SABINE,
-} from '../../../support/data.util';
+import { ORGANISATIONSEINHEITEN_ID_FOR_ADELHEIT, ORGANISATIONSEINHEITEN_ID_FOR_SABINE } from '../../../support/data.util';
 import { MessagesE2E } from '../../../support/messages';
 import { loginAsAdelheit, loginAsSabine } from '../../../support/user-util';
 import { buildVorgang, createVorgang, initVorgaenge } from '../../../support/vorgang-util';
@@ -72,10 +69,6 @@ describe('PostfachNachrichten filtered by organisationseinheit', () => {
     initVorgaenge([vorgangForSabine, vorgangForAdelheit]);
   });
 
-  after(() => {
-    dropCollections();
-  });
-
   describe('on user sabine', () => {
     const authorizedUrl = vorgangUrlVisibleToSabine;
     const forbiddenUrl = vorgangUrlVisibleToAdelheit;
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.cy.ts
index cb4a23f20e..8fc722691d 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-authorize-by-role.cy.ts
@@ -25,7 +25,7 @@ import { SnackBarE2EComponent } from 'apps/alfa-e2e/src/components/ui/snackbar.e
 import { VorgangE2E, VorgangStatusE2E } from 'apps/alfa-e2e/src/model/vorgang';
 import { MainPage, waitForSpinnerToDisappear } from 'apps/alfa-e2e/src/page-objects/main.po';
 import { PostfachMailPage } from 'apps/alfa-e2e/src/page-objects/postfach-mail.component.po';
-import { dropCollections, visitUrl } from 'apps/alfa-e2e/src/support/cypress-helper';
+import { visitUrl } from 'apps/alfa-e2e/src/support/cypress-helper';
 import { contains, exist, notExist } from 'apps/alfa-e2e/src/support/cypress.util';
 import { MessagesE2E } from 'apps/alfa-e2e/src/support/messages';
 import { createPostfachUriByVorgangId } from 'apps/alfa-e2e/src/support/postfach-util';
@@ -47,47 +47,32 @@ describe('Postfach Nachricht should be authorized by role', () => {
     };
 
     const vorgangInStatusInBearbeitungId = '60250b9d383c182943f6ba79';
-    const vorgangInStatusInBearbeitungUrl: string = createPostfachUriByVorgangId(
-      vorgangInStatusInBearbeitungId,
-    );
+    const vorgangInStatusInBearbeitungUrl: string = createPostfachUriByVorgangId(vorgangInStatusInBearbeitungId);
     const vorgangInStatusInBearbeitung: VorgangE2E = {
       ...buildVorgang(vorgangInStatusInBearbeitungId, 'vorgangInStatusInBearbeitung'),
       status: VorgangStatusE2E.IN_BEARBEITUNG,
     };
 
     const vorgangInStatusAbgeschlossenId: string = '602566a807bb665df9a86e87';
-    const vorgangInStatusAbgeschlossenUrl: string = createPostfachUriByVorgangId(
-      vorgangInStatusAbgeschlossenId,
-    );
+    const vorgangInStatusAbgeschlossenUrl: string = createPostfachUriByVorgangId(vorgangInStatusAbgeschlossenId);
     const vorgangInStatusAbgeschlossen: VorgangE2E = {
       ...buildVorgang(vorgangInStatusAbgeschlossenId, 'vorgangInStatusAbgeschlossen'),
       status: VorgangStatusE2E.ABGESCHLOSSEN,
     };
 
     const vorgangInStatusBeschiedenId: string = '602566a207bb665df9a86e86';
-    const vorgangInStatusBeschiedenUrl: string = createPostfachUriByVorgangId(
-      vorgangInStatusBeschiedenId,
-    );
+    const vorgangInStatusBeschiedenUrl: string = createPostfachUriByVorgangId(vorgangInStatusBeschiedenId);
     const vorgangInStatusBeschieden: VorgangE2E = {
       ...buildVorgang(vorgangInStatusBeschiedenId, 'vorgangInStatusBeschieden'),
       status: VorgangStatusE2E.BESCHIEDEN,
     };
 
     beforeEach(() => {
-      initVorgaenge([
-        vorgangInStatusNeu,
-        vorgangInStatusInBearbeitung,
-        vorgangInStatusAbgeschlossen,
-        vorgangInStatusBeschieden,
-      ]);
+      initVorgaenge([vorgangInStatusNeu, vorgangInStatusInBearbeitung, vorgangInStatusAbgeschlossen, vorgangInStatusBeschieden]);
 
       loginAsPeter();
     });
 
-    after(() => {
-      dropCollections();
-    });
-
     it(`should show vorgang in Stauts ${VorgangStatusE2E.NEU}`, () => {
       visitUrl(vorgangInStatusNeuUrl);
       waitForSpinnerToDisappear();
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts
new file mode 100644
index 0000000000..d2c1d45bf3
--- /dev/null
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts
@@ -0,0 +1,67 @@
+import { PostfachMailE2EComponent } from 'apps/alfa-e2e/src/components/postfach/postfach-mail.e2e.component';
+import { E2EAppHelper } from 'apps/alfa-e2e/src/helper/app.helper';
+import { E2EVorgangNavigator } from 'apps/alfa-e2e/src/helper/vorgang/vorgang.navigator';
+import { CommandE2E, CommandOrderE2E, CommandStatusE2E } from 'apps/alfa-e2e/src/model/command';
+import { createCommand, initCommand } from 'apps/alfa-e2e/src/support/command-util';
+import {
+  createPostfachNachrichtAttachedItem,
+  createSendPostfachNachrichtItem,
+} from 'apps/alfa-e2e/src/support/postfach-nachricht.util';
+import { initVorgangAttachedItem } from 'apps/alfa-e2e/src/support/vorgang-attached-item-util';
+import { VorgangE2E } from '../../../model/vorgang';
+import { PostfachMailItemE2E, VorgangAttachedItemE2E } from '../../../model/vorgang-attached-item';
+import { containsSpinner } from '../../../page-objects/main.po';
+import { VorgangPage } from '../../../page-objects/vorgang.po';
+import { exist } from '../../../support/cypress.util';
+import { createVorgang, initVorgang, objectIds } from '../../../support/vorgang-util';
+
+describe('Postfach Nachricht pending send', () => {
+  const appHelper: E2EAppHelper = new E2EAppHelper();
+
+  const vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator();
+
+  const vorgangPage: VorgangPage = new VorgangPage();
+  const postfachMailContainer: PostfachMailE2EComponent = vorgangPage.getPostfachMailcontainer();
+
+  const vorgangWithPendingSendCommand: VorgangE2E = { ...createVorgang(), name: 'VorgangWithPendingSendCommand' };
+  const postfachSendNachrichtItem: PostfachMailItemE2E = {
+    ...createSendPostfachNachrichtItem(),
+    sentSuccessful: false,
+  };
+  const postfachNachrichtAttachedItem: VorgangAttachedItemE2E = {
+    ...createPostfachNachrichtAttachedItem(objectIds[1], vorgangWithPendingSendCommand._id.$oid),
+    item: postfachSendNachrichtItem,
+  };
+  const pendingSendCommand: CommandE2E = {
+    ...createCommand(),
+    order: CommandOrderE2E.SEND_POSTFACH_NACHRICHT,
+    status: CommandStatusE2E.PENDING,
+    finishedAt: null,
+    body: postfachSendNachrichtItem,
+  };
+
+  before(() => {
+    initVorgang(vorgangWithPendingSendCommand);
+    initVorgangAttachedItem([postfachNachrichtAttachedItem]);
+    initCommand(pendingSendCommand);
+
+    appHelper.loginAsSabine();
+  });
+
+  describe('area in vorgang detail', () => {
+    it('should have item in list', () => {
+      vorgangNavigator.openVorgang(vorgangWithPendingSendCommand.name);
+
+      exist(postfachMailContainer.getListItem(postfachSendNachrichtItem.subject).getRoot());
+    });
+
+    it('should show spinner on buttons', () => {
+      containsSpinner(postfachMailContainer.getCreateButtonWithText());
+      containsSpinner(postfachMailContainer.getCreateButtonWithoutText());
+    });
+
+    it('should show edit button', () => {
+      exist(postfachMailContainer.getListItem(postfachSendNachrichtItem.subject).getEditButton());
+    });
+  });
+});
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts
index ad58b9e3b8..009047f787 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts
@@ -25,7 +25,6 @@ import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-lis
 import { VorgangE2E } from '../../../model/vorgang';
 import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
-import { dropCollections } from '../../../support/cypress-helper';
 import { exist } from '../../../support/cypress.util';
 import { generate12ByteId } from '../../../support/tech.util';
 import { loginAsSabine } from '../../../support/user-util';
@@ -48,9 +47,7 @@ describe('Postfach Nachricht reply button', () => {
         postfachAddress: [
           {
             type: 1,
-            identifier: new Map([
-              ['postfachId', new Object('04d39269-81c5-4838-8b73-08d9567f06d7')],
-            ]),
+            identifier: new Map([['postfachId', new Object('04d39269-81c5-4838-8b73-08d9567f06d7')]]),
           },
         ],
       },
@@ -66,10 +63,6 @@ describe('Postfach Nachricht reply button', () => {
     exist(vorgangList.getRoot());
   });
 
-  after(() => {
-    dropCollections();
-  });
-
   describe('navigate to vorgang detail with OSI service konto', () => {
     it('should open vorgang detail', () => {
       vorgangList.getListItem(vorgangWithOsiServiceKonto.name).getRoot().click();
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts
index d0d6d95237..fa8a20f7a6 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachrichten.cy.ts
@@ -35,12 +35,7 @@ import { VorgangE2E } from '../../../model/vorgang';
 import { PostfachMailItemE2E, VorgangAttachedItemE2E } from '../../../model/vorgang-attached-item';
 import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
-import {
-  countDownloadFiles,
-  deleteDownloadFolder,
-  dropCollections,
-  interceptWithResponse,
-} from '../../../support/cypress-helper';
+import { countDownloadFiles, deleteDownloadFolder, interceptWithResponse } from '../../../support/cypress-helper';
 import { exist, notExist } from '../../../support/cypress.util';
 import { LinkRelE2E } from '../../../support/linkrels';
 import { removeLinkFromResource } from '../../../support/tech.util';
@@ -73,10 +68,6 @@ describe('Postfach Nachrichten', () => {
     exist(vorgangList.getRoot());
   });
 
-  after(() => {
-    dropCollections();
-  });
-
   describe('navigate to vorgangDetail', () => {
     beforeEach(() => {
       interceptWithResponse(HttpMethodE2E.GET, '*/vorgangs/*', (req) => modifyResponse(req));
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forwarding.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forwarding.cy.ts
index 8634b339b8..9ac436d5a3 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forwarding.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-forwarding.cy.ts
@@ -140,7 +140,7 @@ describe('Vorgang weiterleiten', () => {
     });
 
     it('should display Weiterleiten button in Status In Neu', () => {
-      vorgangNavigator.openVorgangDetailByName(vorgangWeiterleiten.name);
+      vorgangNavigator.openVorgang(vorgangWeiterleiten.name);
 
       vorgangVerifier.verifyForwardingButtonExists();
     });
diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/command/command.json b/alfa-client/apps/alfa-e2e/src/fixtures/command/command.json
index 854f9990ea..9b286b5bbd 100644
--- a/alfa-client/apps/alfa-e2e/src/fixtures/command/command.json
+++ b/alfa-client/apps/alfa-e2e/src/fixtures/command/command.json
@@ -1,4 +1,7 @@
 {
+  "_id": {
+    "$oid": "60d9fa33290e586b59a6b311"
+  },
   "vorgangId": "602566a807bb665df9a86111",
   "createdAt": {
     "$date": "2022-06-20T10:51:52.073Z"
@@ -10,8 +13,8 @@
   "relationVersion": 0,
   "order": "SEND_POSTFACH_MAIL",
   "previousStatus": "NEU",
-  "_class": "Command",
   "finishedAt": {
     "$date": "2022-06-20T10:51:53.600Z"
-  }
+  },
+  "_class": "Command"
 }
diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/postfach/send-postfach-nachricht.json b/alfa-client/apps/alfa-e2e/src/fixtures/postfach/send-postfach-nachricht.json
new file mode 100644
index 0000000000..4954c8891b
--- /dev/null
+++ b/alfa-client/apps/alfa-e2e/src/fixtures/postfach/send-postfach-nachricht.json
@@ -0,0 +1,23 @@
+{
+  "attachment": [],
+  "mailBody": "\nSig für Sprint... <b>fix</b> a\n\nMfG\nIhre lustige Behörde",
+  "subject": "Send",
+  "vorgangId": "",
+  "sentAt": "",
+  "postfachAddress": {
+    "serviceKontoType": "OSI",
+    "identifier": {
+      "postfachId": "91ed5efa-9278-4366-e8f9-08db926b26f3"
+    },
+    "type": "1",
+    "version": "1.0",
+    "class": "class de.ozgcloud.alfa.postfach.PostfachAddress"
+  },
+  "createdAt": "2020-12-31T01:01:43.790Z[UTC]",
+  "sentSuccessful": "",
+  "createdBy": "",
+  "messageCode": "",
+  "id": "",
+  "replyOption": "POSSIBLE",
+  "direction": "OUT"
+}
diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ludwig.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ludwig.json
new file mode 100644
index 0000000000..a6dd93d1bc
--- /dev/null
+++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_ludwig.json
@@ -0,0 +1,18 @@
+{
+  "_id": {
+    "$oid": "63284e55c39b316b2ad02a5d"
+  },
+  "createdAt": {
+    "$date": "2022-08-25T08:29:45.025Z"
+  },
+  "deleted": false,
+  "keycloakUserId": "108ee867-7290-466d-813f-ab1dc95d3691",
+  "firstName": "Ludwig",
+  "fullName": "Ludwig Löscher",
+  "lastName": "Lösher",
+  "email": "ludwig.loescher@e2e-ozg-sh.de",
+  "lastSyncTimestamp": 1663585874687,
+  "organisationsEinheitIds": [],
+  "roles": ["VERWALTUNG_LOESCHEN"],
+  "username": "ludwig"
+}
diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zonk.json b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zonk.json
new file mode 100644
index 0000000000..8dd4e48252
--- /dev/null
+++ b/alfa-client/apps/alfa-e2e/src/fixtures/usermanager/usermanager_user_zonk.json
@@ -0,0 +1,18 @@
+{
+  "_id": {
+    "$oid": "63284e54c33b916b2ad02e2a"
+  },
+  "createdAt": {
+    "$date": "2022-08-25T08:29:45.025Z"
+  },
+  "deleted": false,
+  "keycloakUserId": "108ee867-7290-466d-813f-ab1dc95d3691",
+  "firstName": "Zacharias",
+  "fullName": "Zacharias Zonk",
+  "lastName": "Zonk",
+  "email": "zacharias.zonk@e2e-ozg-sh.de",
+  "lastSyncTimestamp": 1663585874687,
+  "organisationsEinheitIds": [],
+  "roles": ["VERWALTUNG_USER"],
+  "username": "zonk"
+}
diff --git a/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.navigator.ts b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.navigator.ts
index 3400d79516..50a60041b6 100644
--- a/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.navigator.ts
+++ b/alfa-client/apps/alfa-e2e/src/helper/forwarding/forwarding.navigator.ts
@@ -10,7 +10,7 @@ export class E2EForwardingNavigator {
   private readonly forwardingDialog: ForwardingDialogE2EComponent = new ForwardingDialogE2EComponent();
 
   public openForwardDialog(vorgangName: string): void {
-    this.vorgangNavigator.openVorgangDetailByName(vorgangName);
+    this.vorgangNavigator.openVorgang(vorgangName);
     this.formularButtons.getForwardButton().click();
     exist(this.forwardingDialog.getRoot());
   }
diff --git a/alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.navigator.ts b/alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.navigator.ts
new file mode 100644
index 0000000000..3b7a2b0a0c
--- /dev/null
+++ b/alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.navigator.ts
@@ -0,0 +1,9 @@
+import { E2EVorgangNavigator } from '../vorgang/vorgang.navigator';
+
+export class E2EPostfachNachrichtNavigator {
+  private readonly vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator();
+
+  public openPostfachNachricht(vorgangName: string): void {
+    this.vorgangNavigator.openVorgang(vorgangName);
+  }
+}
diff --git a/alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.verifier.ts b/alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.verifier.ts
new file mode 100644
index 0000000000..d6f9c0cebf
--- /dev/null
+++ b/alfa-client/apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.verifier.ts
@@ -0,0 +1,27 @@
+import { PostfachMailListItemE2EComponent } from '../../components/postfach/postfach-mail.e2e.component';
+import { PostfachNachrichtMessageCodeMessagesE2E } from '../../model/vorgang-attached-item';
+import { PostfachMailPage } from '../../page-objects/postfach-mail.component.po';
+import { contains, exist } from '../../support/cypress.util';
+
+export class E2EPostfachNachrichtVerifier {
+  private readonly postfachNachrichtPage: PostfachMailPage = new PostfachMailPage();
+
+  public verifyFailedItemInList(subject: string): void {
+    const item: PostfachMailListItemE2EComponent = this.getListItem(subject);
+    this.verifyItemInList(subject);
+    contains(item.getSendErrorText(), PostfachNachrichtMessageCodeMessagesE2E.PROCESSING_FAILED);
+    exist(item.getSendErrorIcon());
+    exist(item.getResendButton());
+  }
+
+  public verifyItemInList(subject: string): void {
+    const item: PostfachMailListItemE2EComponent = this.getListItem(subject);
+    contains(item.getSubject(), subject);
+    exist(item.getUserProfile().getRoot());
+    exist(item.getSentAt());
+  }
+
+  private getListItem(subject: string): PostfachMailListItemE2EComponent {
+    return this.postfachNachrichtPage.getListItem(subject);
+  }
+}
diff --git a/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.navigator.ts b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.navigator.ts
index 3225f82b8a..9642b588d8 100644
--- a/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.navigator.ts
+++ b/alfa-client/apps/alfa-e2e/src/helper/vorgang/vorgang.navigator.ts
@@ -11,16 +11,12 @@ export class E2EVorgangNavigator {
 
   private readonly vorgangListPage = new VorgangListE2EComponent();
 
-  public openVorgangDetailByName(vorgangName: string): void {
-    this.vorgangListPage.getListItem(vorgangName).getRoot().click();
-    waitForSpinnerToDisappear();
-    this.verifier.verifyVorgangDetailOpen(vorgangName);
-  }
-
   public openVorgang(vorgangName: string): void {
     this.appHelper.navigateToDomain();
     waitForSpinnerToDisappear();
     exist(this.vorgangListPage.getRoot());
-    this.openVorgangDetailByName(vorgangName);
+
+    this.vorgangListPage.getListItem(vorgangName).getRoot().click();
+    this.verifier.verifyVorgangDetailOpen(vorgangName);
   }
 }
diff --git a/alfa-client/apps/alfa-e2e/src/model/command.ts b/alfa-client/apps/alfa-e2e/src/model/command.ts
index 537bd8680f..bdc72b43d4 100644
--- a/alfa-client/apps/alfa-e2e/src/model/command.ts
+++ b/alfa-client/apps/alfa-e2e/src/model/command.ts
@@ -21,12 +21,12 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { DateE2E } from './util';
+import { DateE2E, ObjectIdE2E } from './util';
 
 export enum CommandOrderE2E {
   ASSIGN_USER = 'ASSIGN_USER',
   CREATE_ATTACHED_ITEM = 'CREATE_ATTACHED_ITEM',
-  FORWARD_VORGANG = 'REDIRECT_VORGANG', //TODO Rename Order
+  FORWARD_VORGANG = 'REDIRECT_VORGANG',
   FORWARD_SUCCESSFUL = 'FORWARD_SUCCESSFULL', //TODO Rename Order
   FORWARD_FAILED = 'FORWARD_FAILED',
   PATCH_ATTACHED_ITEM = 'PATCH_ATTACHED_ITEM',
@@ -38,7 +38,14 @@ export enum CommandOrderE2E {
   UPDATE_ATTACHED_ITEM = 'UPDATE_ATTACHED_ITEM',
   VORGANG_WIEDEREROEFFNEN = 'VORGANG_WIEDEREROEFFNEN',
 }
+
+export enum CommandStatusE2E {
+  PENDING = 'PENDING',
+  FINISHED = 'FINISHED',
+}
+
 export class CommandE2E {
+  id: ObjectIdE2E;
   vorgangId: string;
   createdAt: DateE2E;
   createdBy: string;
diff --git a/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts b/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts
index 433d726179..d47b4e62dc 100644
--- a/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts
+++ b/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts
@@ -33,9 +33,13 @@ import { InternalServerErrorDialogE2EComponent } from '../components/ui/internal
 import { SnackBarE2EComponent } from '../components/ui/snackbar.e2e.component';
 import { VorgangListE2EComponent } from '../components/vorgang/vorgang-list.e2e.component';
 import { VorgangViewsE2EComponent } from '../components/vorgang/vorgang-views.e2e.component';
+import { getTestElementWithClass } from '../support/cypress-helper';
+import { exist, notExist } from '../support/cypress.util';
 import { HeaderE2EComponent } from './header.po';
 
 export class MainPage {
+  public static readonly SPINNER: string = 'spinner';
+
   private readonly buildInfo: BuildInfoE2EComponent = new BuildInfoE2EComponent();
   private readonly header: HeaderE2EComponent = new HeaderE2EComponent();
   private readonly navigation: NavigationE2EComponent = new NavigationE2EComponent();
@@ -95,10 +99,20 @@ export class MainPage {
   }
 }
 
-export function waitForSpinnerToDisappear(): boolean {
-  return cy.getTestElementWithClass('spinner').should('not.exist');
+export function waitForSpinnerToDisappear(): void {
+  notExist(getSpinner());
+}
+
+export function getSpinner(): Cypress.Chainable<JQuery<Element>> {
+  return getTestElementWithClass(MainPage.SPINNER);
+}
+
+export function containsSpinner(rootElement: Cypress.Chainable<JQuery<Element>>): void {
+  exist(rootElement.findTestElementWithClass(MainPage.SPINNER));
 }
 
+//TODO Funktion loeschen
 export function waitforSpinnerToAppear(): void {
   // exist(cy.getTestElementWithClass('spinner'));
 }
+//
diff --git a/alfa-client/apps/alfa-e2e/src/page-objects/postfach-mail.component.po.ts b/alfa-client/apps/alfa-e2e/src/page-objects/postfach-mail.component.po.ts
index c76682e1c2..50d8ffd1fb 100644
--- a/alfa-client/apps/alfa-e2e/src/page-objects/postfach-mail.component.po.ts
+++ b/alfa-client/apps/alfa-e2e/src/page-objects/postfach-mail.component.po.ts
@@ -23,7 +23,7 @@
  */
 //TODO Datei umbenennen in postfach.po.ts
 import { PostfachMailSubnavigation } from '../components/postfach/postfach-mail-subnavigation.e2e.component';
-import { PostfachMailListItem } from '../components/postfach/postfach-mail.e2e.component';
+import { PostfachMailListItemE2EComponent } from '../components/postfach/postfach-mail.e2e.component';
 
 export class PostfachMailPage {
   private readonly root: string = 'postfach-mail-list';
@@ -50,8 +50,8 @@ export class PostfachMailPage {
     return this.headingText;
   }
 
-  getListItem(subject: string): PostfachMailListItem {
-    return new PostfachMailListItem(subject);
+  getListItem(subject: string): PostfachMailListItemE2EComponent {
+    return new PostfachMailListItemE2EComponent(subject);
   }
 
   getDownloadButton() {
diff --git a/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts b/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts
index 9e520f34e3..8bdfdfa1e0 100644
--- a/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts
+++ b/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts
@@ -192,6 +192,10 @@ export function getTestElement(value: string) {
   return cy.getTestElement(value);
 }
 
+export function getTestElementWithClass(value: string): Cypress.Chainable<JQuery<Element>> {
+  return cy.getTestElementWithClass(value);
+}
+
 export function getElement(value: string) {
   return cy.get(value);
 }
diff --git a/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts b/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts
index 0c4ad2fdcb..335686bf99 100644
--- a/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts
+++ b/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts
@@ -160,7 +160,8 @@ function parseCommandData(commands) {
   return commands;
 }
 
-function parseCommand(command) {
+function parseCommand(command): void {
+  command._id = createObjectId(command);
   command.createdAt = createDate(command.createdAt);
   if (command.finishedAt) {
     command.finishedAt = createDate(command.finishedAt);
@@ -173,7 +174,7 @@ function parseGridFsFileData(gridFsFiles) {
   return gridFsFiles;
 }
 
-function parseGridFsFile(gridFsFile) {
+function parseGridFsFile(gridFsFile): void {
   gridFsFile._id = createObjectId(gridFsFile);
   gridFsFile.length = createNumberLong(gridFsFile.length);
   gridFsFile.uploadDate = createDate(gridFsFile.uploadDate);
@@ -184,7 +185,7 @@ function parseGridFsChunkData(gridFsChunks) {
   return gridFsChunks;
 }
 
-function parseGridFsChunk(gridFsChunk) {
+function parseGridFsChunk(gridFsChunk): void {
   gridFsChunk._id = createObjectId(gridFsChunk);
   //TODO createObjectId nutzen, sobald diese umgestellt ist
   gridFsChunk.files_id = new ObjectId(gridFsChunk.files_id.$oid);
@@ -196,18 +197,18 @@ function parseOzgCloudFileData(ozgCloudFiles: OzgCloudFileE2E[]) {
   return ozgCloudFiles;
 }
 
-function parseOzgCloudFile(ozgCloudFile) {
+function parseOzgCloudFile(ozgCloudFile): void {
   ozgCloudFile._id = createObjectId(ozgCloudFile);
   ozgCloudFile.size = createNumberLong(ozgCloudFile.size);
   ozgCloudFile.version = createNumberLong(ozgCloudFile.version);
 }
 
-function parseVorgangData(data) {
+function parseVorgangData(data): void {
   data.forEach((vorgang) => parseVorgang(vorgang));
   return data;
 }
 
-function parseVorgang(vorgang) {
+function parseVorgang(vorgang): void {
   vorgang._id = createObjectId(vorgang);
   vorgang.createdAt = createDate(vorgang.createdAt);
 
@@ -221,7 +222,7 @@ function parseVorgang(vorgang) {
   }
 }
 
-function parseEingang(eingang) {
+function parseEingang(eingang): void {
   eingang.header.createdAt = createDate(eingang.header.createdAt);
 }
 
@@ -229,16 +230,16 @@ function createBinData(encoded64Value) {
   return Binary(Buffer.from(encoded64Value, 'base64'), 0);
 }
 
-function parseWiedervorlage(wiedervorlage) {
+function parseWiedervorlage(wiedervorlage): void {
   wiedervorlage.frist = createDate(wiedervorlage.frist);
   wiedervorlage.createdAt = createDate(wiedervorlage.createdAt);
 }
 
-function parseKommentar(kommentar) {
+function parseKommentar(kommentar): void {
   kommentar.createdAt = createDate(kommentar.createdAt);
 }
 
-function createDate(field) {
+function createDate(field): Date {
   return new Date(field.$date);
 }
 
@@ -247,7 +248,7 @@ function parseVorgangAttachedItemData(vorgangAttachedItems) {
   return vorgangAttachedItems;
 }
 
-function parseVorgangAttachedItem(parseVorgangAttachedItem) {
+function parseVorgangAttachedItem(parseVorgangAttachedItem): void {
   parseVorgangAttachedItem._id = createObjectId(parseVorgangAttachedItem);
   parseVorgangAttachedItem.version = createNumberLong(parseVorgangAttachedItem.version);
 }
@@ -257,7 +258,7 @@ function parseUserData(data) {
   return data;
 }
 
-function parseUser(user) {
+function parseUser(user): void {
   user._id = createObjectId(user);
   user.createdAt = createDate(user.createdAt);
 }
diff --git a/alfa-client/apps/alfa-e2e/src/support/e2e.ts b/alfa-client/apps/alfa-e2e/src/support/e2e.ts
index ee993cca1c..6334e8ea63 100644
--- a/alfa-client/apps/alfa-e2e/src/support/e2e.ts
+++ b/alfa-client/apps/alfa-e2e/src/support/e2e.ts
@@ -41,6 +41,7 @@ import 'cypress-mochawesome-reporter/register';
 import 'cypress-real-events';
 import 'cypress-timestamps/support';
 import './commands';
+import { dropCollections } from './cypress-helper';
 import './file-upload';
 
 Cypress.on('command:start', ({ attributes }) => {
@@ -66,3 +67,9 @@ Cypress.on('fail', (err) => {
 Cypress.Keyboard.defaults({
   keystrokeDelay: 30,
 });
+
+after(() => {
+  cy.log('Cleanup after test suite...');
+  dropCollections();
+  cy.log('...cleanup done.');
+});
diff --git a/alfa-client/apps/alfa-e2e/src/support/postfach-nachricht.util.ts b/alfa-client/apps/alfa-e2e/src/support/postfach-nachricht.util.ts
index ce4a9c9587..6b661b1da1 100644
--- a/alfa-client/apps/alfa-e2e/src/support/postfach-nachricht.util.ts
+++ b/alfa-client/apps/alfa-e2e/src/support/postfach-nachricht.util.ts
@@ -4,9 +4,11 @@ import {
   VorgangAttachedItemE2E,
   VorgangAttachedItemNameE2E,
 } from '../model/vorgang-attached-item';
+import { getUserSabineId } from './user-util';
 import { VORGANG_ATTACHED_ITEM_CLASS } from './vorgang-attached-item-util';
 
 const postfachNachrichtReplyItemFixture: PostfachMailItemE2E = require('../fixtures/postfach/postfach-nachricht-reply-item.json');
+const sendPostfachNachrichtCommandFixture: PostfachMailItemE2E = require('../fixtures/postfach/send-postfach-nachricht.json');
 
 export function createPostfachNachrichtReplyItem(): PostfachMailItemE2E {
   return postfachNachrichtReplyItemFixture;
@@ -27,3 +29,7 @@ export function createPostfachNachrichtAttachedItem(_id: string, vorgangId: stri
     _class: VORGANG_ATTACHED_ITEM_CLASS,
   };
 }
+
+export function createSendPostfachNachrichtItem(): PostfachMailItemE2E {
+  return { ...sendPostfachNachrichtCommandFixture, createdBy: getUserSabineId() };
+}
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-button-container/postfach-mail-button/postfach-mail-button.component.html b/alfa-client/libs/postfach/src/lib/postfach-mail-button-container/postfach-mail-button/postfach-mail-button.component.html
index eff1422c21..33bdf6e2f6 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-button-container/postfach-mail-button/postfach-mail-button.component.html
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-button-container/postfach-mail-button/postfach-mail-button.component.html
@@ -24,7 +24,6 @@
 
 -->
 @if (postfachMailListStateResource.resource | hasLink: postfachMailListLinkRel.SEND_POSTFACH_MAIL) {
-  <!-- TODO Aufteilen in 3 einzelne Komponenten -->
   @if (showAsIconButton) {
     <ods-button
       dataTestId="send-mail-icon-button"
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.html b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.html
index 948be283b5..1e21300e35 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.html
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.html
@@ -25,19 +25,19 @@
 -->
 <a [routerLink]="onPage ? null : 'postfach'" data-test-class="incoming-mail-routing">
   <div class="mail-head">
-    <div class="subject" data-test-id="mail-subject">
-      <mat-icon data-test-id="reply-icon">reply</mat-icon>
+    <div class="subject" data-test-class="mail-subject">
+      <mat-icon data-test-class="reply-icon">reply</mat-icon>
       <span class="overflow">{{ postfachMail.subject }}</span>
     </div>
     <alfa-postfach-mail-date class="date" [postfachMail]="postfachMail"></alfa-postfach-mail-date>
   </div>
   <div class="second-row">
-    <div class="message overflow" data-test-id="mail-text">
+    <div class="message overflow" data-test-class="mail-text">
       {{ postfachMail.mailBody }}
     </div>
     <mat-icon
       *ngIf="(postfachMail | hasLink: postfachNachrichtLinkRel.ATTACHMENTS) && !onPage"
-      data-test-id="postfach-nachricht-attachment-icon"
+      data-test-class="postfach-nachricht-attachment-icon"
       >attach_file</mat-icon
     >
   </div>
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.spec.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.spec.ts
index 7ef16d31fb..6aa766b89b 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.spec.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/incomming-mail/incomming-mail.component.spec.ts
@@ -29,7 +29,7 @@ import localeDe from '@angular/common/locales/de';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MatIcon } from '@angular/material/icon';
 import { provideRouter, RouterLinkWithHref, RouterModule } from '@angular/router';
-import { getDataTestClassOf, getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { getDataTestClassOf } from 'libs/tech-shared/test/data-test';
 import { MockComponent } from 'ng-mocks';
 import { createPostfachMailResource } from '../../../../../../../postfach-shared/test/postfach';
 import { PostfachMailDateComponent } from '../postfach-mail-date/postfach-mail-date.component';
@@ -41,7 +41,7 @@ describe('IncommingMailComponent', () => {
   let component: IncommingMailComponent;
   let fixture: ComponentFixture<IncommingMailComponent>;
 
-  const attachmentIcon: string = getDataTestIdOf('postfach-nachricht-attachment-icon');
+  const attachmentIcon: string = getDataTestClassOf('postfach-nachricht-attachment-icon');
   const routing: string = getDataTestClassOf('incoming-mail-routing');
 
   beforeEach(async () => {
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.html b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.html
index e77aa1c04b..b0350e73cf 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.html
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.html
@@ -24,7 +24,7 @@
 
 -->
 <alfa-outgoing-mail-error
-  *ngIf="postfachMailResource | hasLink: postfachMailLinkRel.RESEND_POSTFACH_MAIL"
+  *ngIf="postfachMailResource | hasLink: PostfachMailLinkRel.RESEND_POSTFACH_MAIL"
   data-test-id="outgoing-mail-error"
   [postfachMailResource]="postfachMailResource"
   [resendPostfachMailStateResource]="resendPostfachMailStateResource$ | async"
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts
index 43ea6995be..20855cb121 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts
@@ -21,30 +21,33 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { OutgoingMailErrorContainerComponent } from './outgoing-mail-error-container.component';
+import { CommandResource } from '@alfa-client/command-shared';
 import { PostfachMailLinkRel, PostfachService } from '@alfa-client/postfach-shared';
-import { mock } from '@alfa-client/test-utils';
-import { OutgoingMailErrorComponent } from './outgoing-mail-error/outgoing-mail-error.component';
+import { createEmptyStateResource, createStateResource, HasLinkPipe, StateResource } from '@alfa-client/tech-shared';
+import { existsAsHtmlElement, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { createCommandResource } from 'libs/command-shared/test/command';
+import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
 import { MockComponent } from 'ng-mocks';
-import { HasLinkPipe } from '@alfa-client/tech-shared';
+import { of } from 'rxjs';
 import { createPostfachMailResource } from '../../../../../../../../postfach-shared/test/postfach';
+import { singleColdCompleted } from '../../../../../../../../tech-shared/test/marbles';
+import { OutgoingMailErrorContainerComponent } from './outgoing-mail-error-container.component';
+import { OutgoingMailErrorComponent } from './outgoing-mail-error/outgoing-mail-error.component';
 
 describe('OutgoingMailErrorContainerComponent', () => {
   let component: OutgoingMailErrorContainerComponent;
   let fixture: ComponentFixture<OutgoingMailErrorContainerComponent>;
 
-  const postfachService = mock(PostfachService);
-  const mailError: string = '[data-test-id="outgoing-mail-error"]';
+  let postfachService: Mock<PostfachService>;
+
+  const mailError: string = getDataTestIdOf('outgoing-mail-error');
 
   beforeEach(async () => {
+    postfachService = mock(PostfachService);
+
     await TestBed.configureTestingModule({
-      declarations: [
-        OutgoingMailErrorContainerComponent,
-        MockComponent(OutgoingMailErrorComponent),
-        HasLinkPipe,
-      ],
+      declarations: [OutgoingMailErrorContainerComponent, MockComponent(OutgoingMailErrorComponent), HasLinkPipe],
       providers: [
         {
           provide: PostfachService,
@@ -65,32 +68,42 @@ describe('OutgoingMailErrorContainerComponent', () => {
   });
 
   describe('resendMail', () => {
+    const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource());
+
+    beforeEach(() => {
+      postfachService.resendMail.mockReturnValue(of(commandStateResource));
+    });
+
     it('should call postfach service', () => {
       component.resendMail();
 
       expect(postfachService.resendMail).toHaveBeenCalled();
     });
+
+    it('should assign service response', () => {
+      component.resendPostfachMailStateResource$ = of(createEmptyStateResource<CommandResource>());
+
+      component.resendMail();
+
+      expect(component.resendPostfachMailStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
   });
 
   describe('outgoing mail error', () => {
     it('should show', () => {
-      component.postfachMailResource = createPostfachMailResource([
-        PostfachMailLinkRel.RESEND_POSTFACH_MAIL,
-      ]);
-      fixture.detectChanges();
+      component.postfachMailResource = createPostfachMailResource([PostfachMailLinkRel.RESEND_POSTFACH_MAIL]);
 
-      const element = fixture.nativeElement.querySelector(mailError);
+      fixture.detectChanges();
 
-      expect(element).toBeInstanceOf(HTMLElement);
+      existsAsHtmlElement(fixture, mailError);
     });
 
     it('should hide', () => {
       component.postfachMailResource = createPostfachMailResource();
-      fixture.detectChanges();
 
-      const element = fixture.nativeElement.querySelector(mailError);
+      fixture.detectChanges();
 
-      expect(element).not.toBeInstanceOf(HTMLElement);
+      notExistsAsHtmlElement(fixture, mailError);
     });
   });
 });
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts
index 680063ef32..c0d8d6589d 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts
@@ -21,15 +21,11 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { Component, Input, OnInit } from '@angular/core';
-import { StateResource } from '@alfa-client/tech-shared';
 import { CommandResource } from '@alfa-client/command-shared';
+import { PostfachMailLinkRel, PostfachMailResource, PostfachService } from '@alfa-client/postfach-shared';
+import { StateResource } from '@alfa-client/tech-shared';
+import { Component, inject, Input, OnInit } from '@angular/core';
 import { Observable } from 'rxjs';
-import {
-  PostfachMailLinkRel,
-  PostfachMailResource,
-  PostfachService,
-} from '@alfa-client/postfach-shared';
 
 @Component({
   selector: 'alfa-outgoing-mail-error-container',
@@ -39,18 +35,17 @@ import {
 export class OutgoingMailErrorContainerComponent implements OnInit {
   @Input() postfachMailResource: PostfachMailResource;
 
-  resendPostfachMailStateResource$: Observable<StateResource<CommandResource>>;
+  private readonly postfachService: PostfachService = inject(PostfachService);
 
-  readonly postfachMailLinkRel = PostfachMailLinkRel;
+  public resendPostfachMailStateResource$: Observable<StateResource<CommandResource>>;
 
-  constructor(private postfachService: PostfachService) {}
+  public readonly PostfachMailLinkRel = PostfachMailLinkRel;
 
-  resendMail() {
-    this.postfachService.resendMail(this.postfachMailResource);
+  ngOnInit() {
+    this.resendPostfachMailStateResource$ = this.postfachService.getPendingSendPostfachMailCommand();
   }
 
-  ngOnInit() {
-    this.resendPostfachMailStateResource$ =
-      this.postfachService.getPendingSendPostfachMailCommand();
+  public resendMail(): void {
+    this.resendPostfachMailStateResource$ = this.postfachService.resendMail(this.postfachMailResource);
   }
 }
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error/outgoing-mail-error.component.html b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error/outgoing-mail-error.component.html
index 2eaa38bcef..ee571d9b2d 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error/outgoing-mail-error.component.html
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error/outgoing-mail-error.component.html
@@ -23,19 +23,13 @@
     unter der Lizenz sind dem Lizenztext zu entnehmen.
 
 -->
-<div
-  *ngIf="postfachMailResource.messageCode"
-  data-test-id="mail-send-error"
-  class="mail-send-error"
->
-  <span data-test-id="mail-send-error-text">{{ message }}</span>
-  <mat-icon data-test-id="mail-send-error-icon" class="mail-send-error__icon text-error"
-    >error_outline_white</mat-icon
-  >
+<div *ngIf="postfachMailResource.messageCode" data-test-id="mail-send-error" class="mail-send-error">
+  <span data-test-class="mail-send-error-text">{{ message }}</span>
+  <mat-icon data-test-class="mail-send-error-icon" class="mail-send-error__icon text-error">error_outline_white</mat-icon>
 </div>
 <!-- TODO Eigene Component fuer den Button -->
 <ozgcloud-stroked-button-with-spinner
-  dataTestId="mail-resend-button"
+  dataTestClass="resend-nachricht-button"
   text="Erneut versuchen"
   icon="autorenew"
   [stateResource]="resendPostfachMailStateResource"
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.html b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.html
index a3d8233fcc..8c3c6ee468 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.html
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.html
@@ -38,18 +38,18 @@
     <alfa-postfach-mail-date
       *ngIf="postfachMail.sentAt"
       [postfachMail]="postfachMail"
-      data-test-id="postfach-outgoing-nachricht-date"
+      data-test-class="postfach-outgoing-nachricht-date"
     ></alfa-postfach-mail-date>
   </div>
 
-  <span class="overflow subject" data-test-id="mail-subject">{{ postfachMail.subject }}</span>
-  <div class="message overflow" data-test-id="mail-text">
+  <span class="overflow subject" data-test-class="mail-subject">{{ postfachMail.subject }}</span>
+  <div class="message overflow" data-test-class="mail-text">
     {{ postfachMail.mailBody }}
   </div>
 
   <mat-icon
     *ngIf="(postfachMail | hasLink: postfachNachrichtLinkRel.ATTACHMENTS) && !onPage"
-    data-test-id="postfach-nachricht-attachment-icon"
+    data-test-class="postfach-nachricht-attachment-icon"
     >attach_file</mat-icon
   >
 </a>
@@ -57,7 +57,7 @@
 <alfa-outgoing-mail-error-container [postfachMailResource]="postfachMail"></alfa-outgoing-mail-error-container>
 <alfa-postfach-nachricht-edit-button-container
   *ngIf="(postfachMail | hasLink: postfachNachrichtLinkRel.EDIT) && !onPage"
-  data-test-id="postfach-nachricht-edit-button-container"
+  data-test-class="postfach-nachricht-edit-button-container"
   [postfachNachricht]="postfachMail"
   [vorgangStateResource]="vorgangStateResource"
 >
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.spec.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.spec.ts
index 1c5549014c..09aa734b77 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.spec.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail.component.spec.ts
@@ -35,7 +35,7 @@ import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MatIcon } from '@angular/material/icon';
 import { provideRouter, RouterLinkWithHref, RouterModule } from '@angular/router';
-import { getDataTestClassOf, getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { getDataTestClassOf } from 'libs/tech-shared/test/data-test';
 import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
 import { MockComponent } from 'ng-mocks';
 import { createPostfachMailResource } from '../../../../../../../postfach-shared/test/postfach';
@@ -48,9 +48,9 @@ describe('OutgoingMailComponent', () => {
   let component: OutgoingMailComponent;
   let fixture: ComponentFixture<OutgoingMailComponent>;
 
-  const attachmentIcon: string = getDataTestIdOf('postfach-nachricht-attachment-icon');
-  const postfachEditButton: string = getDataTestIdOf('postfach-nachricht-edit-button-container');
-  const postfachOutgoingNachrichtDate: string = getDataTestIdOf('postfach-outgoing-nachricht-date');
+  const attachmentIcon: string = getDataTestClassOf('postfach-nachricht-attachment-icon');
+  const postfachEditButton: string = getDataTestClassOf('postfach-nachricht-edit-button-container');
+  const postfachOutgoingNachrichtDate: string = getDataTestClassOf('postfach-outgoing-nachricht-date');
 
   const routing: string = getDataTestClassOf('outgoing-mail-routing');
 
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.html b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.html
index 5b1bd5617b..0355d59f69 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.html
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.html
@@ -24,12 +24,12 @@
 
 -->
 <ng-container *ngIf="isIncomingMail; else sentAt">
-  <div class="date" data-test-id="mail-created-at">
+  <div class="date" data-test-class="mail-created-at">
     {{ postfachMail.createdAt | formatDateWithTimePipe: false }}
   </div>
 </ng-container>
 <ng-template #sentAt>
-  <div class="date" data-test-id="mail-sent-at">
+  <div class="date" data-test-class="mail-sent-at">
     {{ postfachMail.sentAt | formatDateWithTimePipe: false }}
   </div>
 </ng-template>
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.spec.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.spec.ts
index ca8fd42b29..80f60496e9 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.spec.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/postfach-mail-date/postfach-mail-date.component.spec.ts
@@ -28,6 +28,7 @@ import { registerLocaleData } from '@angular/common';
 import localeDe from '@angular/common/locales/de';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { createPostfachMailResource } from 'libs/postfach-shared/test/postfach';
+import { getDataTestClassOf } from 'libs/tech-shared/test/data-test';
 import { PostfachMailDateComponent } from './postfach-mail-date.component';
 
 registerLocaleData(localeDe);
@@ -36,8 +37,8 @@ describe('PostfachMailDateComponent', () => {
   let component: PostfachMailDateComponent;
   let fixture: ComponentFixture<PostfachMailDateComponent>;
 
-  const sentAt: string = '[data-test-id="mail-sent-at"]';
-  const createdAt: string = '[data-test-id="mail-created-at"]';
+  const sentAt: string = getDataTestClassOf('mail-sent-at');
+  const createdAt: string = getDataTestClassOf('mail-created-at');
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html
index 1c6c7d8515..3f72b62337 100644
--- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html
@@ -33,6 +33,7 @@
   [tooltip]="toolTip"
   [class.with-text]="text"
   (click)="clickEmitter.emit($event)"
+  [attr.data-test-class]="dataTestClass"
 >
   <ozgcloud-button-content
     [icon]="icon"
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts
index 36f102a0d7..48acab5184 100644
--- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts
@@ -48,6 +48,7 @@ export class OzgcloudStrokedButtonWithSpinnerComponent implements OnInit {
   @Input() dataTestId: string;
   @Input() showSpinner: boolean = false;
   @Input() strokedButton: boolean = true;
+  @Input() dataTestClass: string;
 
   @Output() public clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
 
-- 
GitLab


From b3b5fff877eb48ebec8cc6124ee820a6879c1834 Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Wed, 2 Apr 2025 09:38:46 +0200
Subject: [PATCH 3/8] OZG-7872 test unit test

---
 .../libs/kommentar-shared/src/lib/kommentar.service.spec.ts     | 2 +-
 .../libs/postfach-shared/src/lib/postfach.service.spec.ts       | 2 +-
 .../ozgcloud-stroked-button-with-spinner.component.html         | 1 -
 .../ozgcloud-stroked-button-with-spinner.component.spec.ts      | 2 +-
 .../ozgcloud-stroked-button-with-spinner.component.ts           | 2 +-
 .../wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts  | 2 +-
 6 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts
index bd09cc77d8..4fa2802ae1 100644
--- a/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts
+++ b/alfa-client/libs/kommentar-shared/src/lib/kommentar.service.spec.ts
@@ -66,7 +66,7 @@ describe('KommentarService', () => {
     navigationService = mock(NavigationService);
     vorgangService = {
       ...mock(VorgangService),
-      getVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)),
+      selectVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)),
     };
     binaryFileService = mock(BinaryFileService);
 
diff --git a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
index 876e08a03d..492502ba27 100644
--- a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
+++ b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
@@ -70,7 +70,7 @@ describe('PostfachService', () => {
   beforeEach(() => {
     vorgangService = {
       ...mock(VorgangService),
-      getVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)),
+      selectVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)),
     };
     navigationService.urlChanged = jest.fn();
     navigationService.urlChanged.mockReturnValue(of(urlChangedParams));
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html
index 3f72b62337..9370aa544d 100644
--- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.html
@@ -25,7 +25,6 @@
 -->
 <button
   mat-stroked-button
-  data-test-class="icon-button"
   [attr.data-test-id]="dataTestId"
   [color]="color"
   [type]="type"
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.spec.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.spec.ts
index ac0307f012..003beefa16 100644
--- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.spec.ts
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.spec.ts
@@ -24,13 +24,13 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MatButton } from '@angular/material/button';
 import { MatRipple } from '@angular/material/core';
+import { TooltipDirective } from '@ods/system';
 import { createCommandResource } from 'libs/command-shared/test/command';
 import { getDataTestClassOf } from 'libs/tech-shared/test/data-test';
 import { MockComponent, MockDirective } from 'ng-mocks';
 import { OzgcloudButtonContentComponent } from '../shared/ozgcloud-button-content/ozgcloud-button-content.component';
 import { OzgcloudStrokedButtonWithSpinnerComponent } from './ozgcloud-stroked-button-with-spinner.component';
 
-import { TooltipDirective } from '@ods/system';
 import * as ResourceUtils from 'libs/tech-shared/src/lib/resource/resource.util';
 
 describe('OzgcloudStrokedButtonWithSpinnerComponent', () => {
diff --git a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts
index 48acab5184..8b9cc56e39 100644
--- a/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts
+++ b/alfa-client/libs/ui/src/lib/ui/ozgcloud-button/ozgcloud-stroked-button-with-spinner/ozgcloud-stroked-button-with-spinner.component.ts
@@ -48,7 +48,7 @@ export class OzgcloudStrokedButtonWithSpinnerComponent implements OnInit {
   @Input() dataTestId: string;
   @Input() showSpinner: boolean = false;
   @Input() strokedButton: boolean = true;
-  @Input() dataTestClass: string;
+  @Input() dataTestClass: string = 'icon-button';
 
   @Output() public clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
 
diff --git a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
index f2513adc3b..2f47bc7ea5 100644
--- a/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
+++ b/alfa-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.spec.ts
@@ -88,7 +88,7 @@ describe('WiedervorlageService', () => {
     binaryFileService = mock(BinaryFileService);
     vorgangService = {
       ...mock(VorgangService),
-      getVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)),
+      selectVorgangWithEingang: jest.fn().mockReturnValue(of(vorgangWithEingangStateResource)),
     };
 
     navigationService.urlChanged.mockReturnValue(of({}));
-- 
GitLab


From b8ddd0983e1df4a8724edb3bb7914379adfb33f9 Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Thu, 3 Apr 2025 08:47:17 +0200
Subject: [PATCH 4/8] OZG-7872 add id to command

---
 .../e2e/main-tests/historie/historie.cy.ts    | 141 ++++++------------
 .../vorgang-xdomea-inhalte.cy.ts              |   5 +-
 .../apps/alfa-e2e/src/model/command.ts        |   2 +-
 .../apps/alfa-e2e/src/support/command-util.ts |   7 +-
 4 files changed, 51 insertions(+), 104 deletions(-)

diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/historie/historie.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/historie/historie.cy.ts
index cd1bd8b8cc..34ed5740b5 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/historie/historie.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/historie/historie.cy.ts
@@ -31,11 +31,7 @@ import {
   WiedervorlageHistorieItemE2EComponent,
 } from 'apps/alfa-e2e/src/components/vorgang/vorgang.formular-daten.historie.e2e.component';
 import { CommandE2E, CommandOrderE2E } from 'apps/alfa-e2e/src/model/command';
-import {
-  HistorieAttachmentE2E,
-  HistorieHeadlineE2E,
-  SYSTEM_USER_NAME,
-} from 'apps/alfa-e2e/src/model/historie';
+import { HistorieAttachmentE2E, HistorieHeadlineE2E, SYSTEM_USER_NAME } from 'apps/alfa-e2e/src/model/historie';
 import { PostfachE2E } from 'apps/alfa-e2e/src/model/postfach-nachricht';
 import { DirectionE2E } from 'apps/alfa-e2e/src/model/vorgang-attached-item';
 import { buildCommand, createCommand, initCommands } from 'apps/alfa-e2e/src/support/command-util';
@@ -50,13 +46,8 @@ import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.
 import { VorgangPage } from '../../../page-objects/vorgang.po';
 import { dropCollections } from '../../../support/cypress-helper';
 import { contains, exist, notExist } from '../../../support/cypress.util';
-import {
-  getUserSabine,
-  getUserSabineId,
-  initUsermanagerUsers,
-  loginAsSabine,
-} from '../../../support/user-util';
-import { createVorgang, initVorgang } from '../../../support/vorgang-util';
+import { getUserSabine, getUserSabineId, initUsermanagerUsers, loginAsSabine } from '../../../support/user-util';
+import { createVorgang, initVorgang, objectIds } from '../../../support/vorgang-util';
 
 registerLocaleData(localeDe, 'de', localeDeExtra);
 
@@ -65,15 +56,14 @@ describe('Historie', () => {
   const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList();
 
   const vorgangPage: VorgangPage = new VorgangPage();
-  const vorgangDatenFormular: VorgangFormularDatenE2EComponent =
-    vorgangPage.getFormularDatenContainer();
+  const vorgangDatenFormular: VorgangFormularDatenE2EComponent = vorgangPage.getFormularDatenContainer();
 
   const vorgangHeader: VorgangDetailHeaderE2EComponent = vorgangPage.getVorgangDetailHeader();
 
   const vorgang: VorgangE2E = createVorgang();
 
   const assignUserCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.ASSIGN_USER, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[1], CommandOrderE2E.ASSIGN_USER, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: { assignedTo: getUserSabineId() },
     createdAt: { $date: '2020-01-01T10:00:00.000Z' },
   };
@@ -83,7 +73,7 @@ describe('Historie', () => {
     item: { ...createKommentar(), attachments: 'DummyAttachment' },
   };
   const createKommentarCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.CREATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[2], CommandOrderE2E.CREATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: createKommentarCommandBody,
     createdAt: { $date: '2020-01-01T10:01:00.000Z' },
   };
@@ -92,21 +82,21 @@ describe('Historie', () => {
     item: { ...createKommentar(), attachments: ['DummyAttachment', 'DummyAttachment2'] },
   };
   const editKommentarCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.UPDATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[3], CommandOrderE2E.UPDATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: editKommentarCommandBody,
     createdAt: { $date: '2020-01-01T10:02:00.000Z' },
   };
 
   const forwardVorgangCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.FORWARD_VORGANG, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[4], CommandOrderE2E.FORWARD_VORGANG, vorgang._id.$oid, vorgang._id.$oid),
     createdAt: { $date: '2020-01-01T10:03:00.000Z' },
   };
   const forwardSuccessfulCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.FORWARD_SUCCESSFUL, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[5], CommandOrderE2E.FORWARD_SUCCESSFUL, vorgang._id.$oid, vorgang._id.$oid),
     createdAt: { $date: '2020-01-01T10:04:00.000Z' },
   };
   const forwardFailedCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.FORWARD_FAILED, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[6], CommandOrderE2E.FORWARD_FAILED, vorgang._id.$oid, vorgang._id.$oid),
     createdAt: { $date: '2020-01-01T10:05:00.000Z' },
   };
 
@@ -117,6 +107,7 @@ describe('Historie', () => {
     attachments: 'dummyAttachment',
   };
   const sendPostfachMailCommand: CommandE2E = {
+    _id: { $oid: objectIds[7] },
     ...createCommand(),
     bodyObject: sendPostfachMailCommandBody,
     createdAt: { $date: '2020-01-01T10:06:00.000Z' },
@@ -128,12 +119,12 @@ describe('Historie', () => {
     attachments: ['dummyAttachment', 'dummyAttachment2'],
   };
   const sendPostfachNachrichtCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.SEND_POSTFACH_NACHRICHT, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[8], CommandOrderE2E.SEND_POSTFACH_NACHRICHT, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: sendPostfachNachrichtCommandBody,
     createdAt: { $date: '2020-01-01T10:07:00.000Z' },
   };
   const receivePostfachNachrichtCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.CREATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[9], CommandOrderE2E.CREATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: {
       itemName: 'PostfachMail',
       item: {
@@ -150,6 +141,7 @@ describe('Historie', () => {
   };
 
   const resendPostfachNachricht: CommandE2E = buildCommand(
+    objectIds[10],
     CommandOrderE2E.RESEND_POSTFACH_NACHRICHT,
     vorgang._id.$oid,
     vorgang._id.$oid,
@@ -160,7 +152,7 @@ describe('Historie', () => {
     attachments: 'DummyAttachment',
   };
   const createWiedervorlageCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.CREATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[11], CommandOrderE2E.CREATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: { itemName: 'Wiedervorlage', item: createWiedervorlageCommandBody },
     createdAt: { $date: '2020-01-01T10:09:00.000Z' },
   };
@@ -170,17 +162,17 @@ describe('Historie', () => {
     done: true,
   };
   const editWiedervorlageCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.UPDATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[12], CommandOrderE2E.UPDATE_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: { itemName: 'Wiedervorlage', item: editWiedervorlageCommandBody },
     createdAt: { $date: '2020-01-01T10:10:00.000Z' },
   };
   const wiedervorlageErledigenCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.PATCH_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[13], CommandOrderE2E.PATCH_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: { itemName: 'Wiedervorlage', item: { done: 'true' }, vorgangId: vorgang._id.$oid },
     createdAt: { $date: '2020-01-01T10:11:00.000Z' },
   };
   const wiedervorlageWiedereroeffnenCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.PATCH_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
+    ...buildCommand(objectIds[14], CommandOrderE2E.PATCH_ATTACHED_ITEM, vorgang._id.$oid, vorgang._id.$oid),
     bodyObject: { itemName: 'Wiedervorlage', item: { done: 'false' }, vorgangId: vorgang._id.$oid },
     createdAt: { $date: '2020-01-01T10:12:00.000Z' },
   };
@@ -241,8 +233,7 @@ describe('Historie', () => {
 
         describe('vorgang order', () => {
           it('assign user', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(0);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(0);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.ASSIGN_USER);
@@ -253,8 +244,7 @@ describe('Historie', () => {
 
         describe('kommentar order', () => {
           it('create kommentar', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(1);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(1);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.CREATE_KOMMENTAR);
@@ -268,8 +258,7 @@ describe('Historie', () => {
           });
 
           it('edit kommentar', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(2);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(2);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.EDIT_KOMMENTAR);
@@ -279,17 +268,13 @@ describe('Historie', () => {
             const kommentarItem: KommentarHistorieItemE2EComponent = historieItem.getKommentar();
 
             contains(kommentarItem.getText(), editKommentarCommandBody.item.text);
-            contains(
-              kommentarItem.getAttachment(),
-              HistorieAttachmentE2E.MULTIPLE_TEXT.replace('{countAttachments}', '2'),
-            );
+            contains(kommentarItem.getAttachment(), HistorieAttachmentE2E.MULTIPLE_TEXT.replace('{countAttachments}', '2'));
           });
         });
 
         describe('forward order', () => {
           it('forward vorgang', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(3);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(3);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.FORWARD_VORGANG);
@@ -298,8 +283,7 @@ describe('Historie', () => {
           });
 
           it('forward successful', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(4);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(4);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.FORWARD_SUCCESSFUL);
@@ -308,8 +292,7 @@ describe('Historie', () => {
           });
 
           it('forward failed', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(5);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(5);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.FORWARD_FAILED);
@@ -320,52 +303,35 @@ describe('Historie', () => {
 
         describe('postfach nachricht order', () => {
           it('send postfach mail', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(6);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(6);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.SEND_POSTFACH_NACHRICHT);
             contains(historieItem.getUser(), userName);
 
             historieItem.getExpandButton().click();
-            const postfachNachtichtItem: PostfachNachrichtHistorieItemE2EComponent =
-              historieItem.getPostfachNachricht();
+            const postfachNachtichtItem: PostfachNachrichtHistorieItemE2EComponent = historieItem.getPostfachNachricht();
 
-            contains(
-              postfachNachtichtItem.getPostfachNachrichtSubject(),
-              sendPostfachMailCommandBody.subject,
-            );
-            contains(
-              postfachNachtichtItem.getPostfachNachrichtMailBody(),
-              sendPostfachMailCommandBody.mailBody,
-            );
+            contains(postfachNachtichtItem.getPostfachNachrichtSubject(), sendPostfachMailCommandBody.subject);
+            contains(postfachNachtichtItem.getPostfachNachrichtMailBody(), sendPostfachMailCommandBody.mailBody);
           });
 
           it('send postfach nachricht', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(7);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(7);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.SEND_POSTFACH_NACHRICHT);
             contains(historieItem.getUser(), userName);
 
             historieItem.getExpandButton().click();
-            const postfachNachtichtItem: PostfachNachrichtHistorieItemE2EComponent =
-              historieItem.getPostfachNachricht();
+            const postfachNachtichtItem: PostfachNachrichtHistorieItemE2EComponent = historieItem.getPostfachNachricht();
 
-            contains(
-              postfachNachtichtItem.getPostfachNachrichtSubject(),
-              sendPostfachNachrichtCommandBody.subject,
-            );
-            contains(
-              postfachNachtichtItem.getPostfachNachrichtMailBody(),
-              sendPostfachNachrichtCommandBody.mailBody,
-            );
+            contains(postfachNachtichtItem.getPostfachNachrichtSubject(), sendPostfachNachrichtCommandBody.subject);
+            contains(postfachNachtichtItem.getPostfachNachrichtMailBody(), sendPostfachNachrichtCommandBody.mailBody);
           });
 
           it('receive postfach nachricht', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(8);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(8);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.RECEIVE_POSTFACH_NACHRICHT);
@@ -373,8 +339,7 @@ describe('Historie', () => {
             contains(historieItem.getSystemUser(), SYSTEM_USER_NAME);
 
             historieItem.getExpandButton().click();
-            const postfachNachtichtItem: PostfachNachrichtHistorieItemE2EComponent =
-              historieItem.getPostfachNachricht();
+            const postfachNachtichtItem: PostfachNachrichtHistorieItemE2EComponent = historieItem.getPostfachNachricht();
 
             contains(
               postfachNachtichtItem.getPostfachNachrichtSubject(),
@@ -387,8 +352,7 @@ describe('Historie', () => {
           });
 
           it('resend postfach nachricht', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(9);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(9);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.RESEND_POSTFACH_NACHRICHT);
@@ -398,53 +362,39 @@ describe('Historie', () => {
 
         describe('wiedervorlage order', () => {
           it('create wiedervorlage', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(10);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(10);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.CREATE_WIEDERVORLAGE);
             contains(historieItem.getUser(), userName);
 
             historieItem.getExpandButton().click();
-            const wiedervorlageItem: WiedervorlageHistorieItemE2EComponent =
-              historieItem.getWiedervorlage();
+            const wiedervorlageItem: WiedervorlageHistorieItemE2EComponent = historieItem.getWiedervorlage();
 
             contains(wiedervorlageItem.getStatus(), 'offen');
             contains(wiedervorlageItem.getBetreff(), createWiedervorlageCommandBody.betreff);
-            contains(
-              wiedervorlageItem.getBeschreibung(),
-              createWiedervorlageCommandBody.beschreibung,
-            );
+            contains(wiedervorlageItem.getBeschreibung(), createWiedervorlageCommandBody.beschreibung);
             contains(wiedervorlageItem.getAttachment(), HistorieAttachmentE2E.SINGLE_TEXT);
           });
 
           it('edit wiedervorlage', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(11);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(11);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.EDIT_WIEDERVORLAGE);
             contains(historieItem.getUser(), userName);
 
             historieItem.getExpandButton().click();
-            const wiedervorlageItem: WiedervorlageHistorieItemE2EComponent =
-              historieItem.getWiedervorlage();
+            const wiedervorlageItem: WiedervorlageHistorieItemE2EComponent = historieItem.getWiedervorlage();
 
             contains(wiedervorlageItem.getStatus(), 'geschlossen');
             contains(wiedervorlageItem.getBetreff(), editWiedervorlageCommandBody.betreff);
-            contains(
-              wiedervorlageItem.getBeschreibung(),
-              editWiedervorlageCommandBody.beschreibung,
-            );
-            contains(
-              wiedervorlageItem.getAttachment(),
-              HistorieAttachmentE2E.MULTIPLE_TEXT.replace('{countAttachments}', '2'),
-            );
+            contains(wiedervorlageItem.getBeschreibung(), editWiedervorlageCommandBody.beschreibung);
+            contains(wiedervorlageItem.getAttachment(), HistorieAttachmentE2E.MULTIPLE_TEXT.replace('{countAttachments}', '2'));
           });
 
           it('wiedervorlage erledigen', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(12);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(12);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.WIEDERVORLAGE_ERLEDIGEN);
@@ -453,8 +403,7 @@ describe('Historie', () => {
           });
 
           it('wiedervorlage wiedereroeffnen', () => {
-            const historieItem: VorgangFormularDatenHistorieItemE2EComponent =
-              vorgangDatenFormular.getHistorieItemByIndex(13);
+            const historieItem: VorgangFormularDatenHistorieItemE2EComponent = vorgangDatenFormular.getHistorieItemByIndex(13);
 
             exist(historieItem.getRoot());
             contains(historieItem.getHeadline(), HistorieHeadlineE2E.WIEDERVORLAGE_WIEDEREROEFFNEN);
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-xdomea-inhalte.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-xdomea-inhalte.cy.ts
index ff177ddcff..9050a22745 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-xdomea-inhalte.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-xdomea/vorgang-xdomea-inhalte.cy.ts
@@ -78,13 +78,14 @@ describe('check xDomea contents', () => {
   };
 
   const assignUserCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.ASSIGN_USER, vorgangExportieren._id.$oid, vorgangExportieren._id.$oid),
+    ...buildCommand(objectIds[1], CommandOrderE2E.ASSIGN_USER, vorgangExportieren._id.$oid, vorgangExportieren._id.$oid),
     bodyObject: { assignedTo: getUserDorotheaId() },
     finishedAt: { $date: '2024-06-20T07:25:30.000Z' },
   };
 
   const changeStatusCommand: CommandE2E = {
     ...buildCommand(
+      objectIds[2],
       CommandOrderE2E.VORGANG_WIEDEREROEFFNEN,
       vorgangExportieren._id.$oid,
 
@@ -95,7 +96,7 @@ describe('check xDomea contents', () => {
   };
 
   const setAktenzeichenCommand: CommandE2E = {
-    ...buildCommand(CommandOrderE2E.SET_AKTENZEICHEN, vorgangExportieren._id.$oid, vorgangExportieren._id.$oid),
+    ...buildCommand(objectIds[3], CommandOrderE2E.SET_AKTENZEICHEN, vorgangExportieren._id.$oid, vorgangExportieren._id.$oid),
     order: CommandOrderE2E.SET_AKTENZEICHEN,
     bodyObject: { aktenzeichen: 'AKT_ENZ_EIC_HEN1' },
     finishedAt: { $date: '2024-06-19T07:25:30.000Z' },
diff --git a/alfa-client/apps/alfa-e2e/src/model/command.ts b/alfa-client/apps/alfa-e2e/src/model/command.ts
index bdc72b43d4..1050041aa9 100644
--- a/alfa-client/apps/alfa-e2e/src/model/command.ts
+++ b/alfa-client/apps/alfa-e2e/src/model/command.ts
@@ -45,7 +45,7 @@ export enum CommandStatusE2E {
 }
 
 export class CommandE2E {
-  id: ObjectIdE2E;
+  _id: ObjectIdE2E;
   vorgangId: string;
   createdAt: DateE2E;
   createdBy: string;
diff --git a/alfa-client/apps/alfa-e2e/src/support/command-util.ts b/alfa-client/apps/alfa-e2e/src/support/command-util.ts
index f70f24389b..2ee84ad777 100644
--- a/alfa-client/apps/alfa-e2e/src/support/command-util.ts
+++ b/alfa-client/apps/alfa-e2e/src/support/command-util.ts
@@ -31,13 +31,10 @@ export function createCommand(): CommandE2E {
   return { ...commandFixture, createdBy: getUserSabineId() };
 }
 
-export function buildCommand(
-  order: CommandOrderE2E,
-  vorgangId: string,
-  relationId: string,
-): CommandE2E {
+export function buildCommand(id: string, order: CommandOrderE2E, vorgangId: string, relationId: string): CommandE2E {
   return {
     ...createCommand(),
+    _id: { $oid: id },
     vorgangId,
     relationId,
     order,
-- 
GitLab


From 5a1e94b975d10db05eb06f00d10ede8e9eab9f52 Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Thu, 3 Apr 2025 18:22:30 +0200
Subject: [PATCH 5/8] OZG-7872 use order and uri for command key in state; add
 pendingCommands to vorgang state; use matching command from state in
 component

---
 .../postfach-mail/postfach-mail-error.cy.ts   |  13 +-
 .../postfach-nachricht-pending-send.cy.ts     |  95 ++++++++++--
 .../apps/alfa-e2e/src/page-objects/main.po.ts |   4 +
 alfa-client/apps/alfa-e2e/src/support/e2e.ts  |   6 +
 .../src/lib/+state/command.actions.ts         |  46 +++---
 .../src/lib/+state/command.effects.spec.ts    |  82 +++-------
 .../src/lib/+state/command.effects.ts         |  41 ++---
 .../src/lib/+state/command.reducer.spec.ts    |  46 +++---
 .../src/lib/+state/command.reducer.ts         |  47 +++---
 .../src/lib/+state/command.selectors.spec.ts  |  29 ++--
 .../src/lib/+state/command.selectors.ts       |  22 +--
 .../command-shared/src/lib/command.linkrel.ts |   1 +
 .../command-shared/src/lib/command.model.ts   |   6 +-
 .../src/lib/command.repository.spec.ts        |  28 ++--
 .../src/lib/command.repository.ts             |  19 +--
 .../src/lib/command.service.spec.ts           |  75 ++++-----
 .../command-shared/src/lib/command.service.ts |  50 +++---
 .../src/lib/command.util.spec.ts              |  46 ++++--
 .../command-shared/src/lib/command.util.ts    |  26 ++--
 .../libs/command-shared/test/command.ts       |   5 +
 .../src/lib/postfach.service.spec.ts          |  35 ++++-
 .../src/lib/postfach.service.ts               |  14 +-
 ...ing-mail-error-container.component.spec.ts |  37 ++++-
 ...outgoing-mail-error-container.component.ts |   4 +-
 .../src/lib/+state/vorgang.actions.ts         | 144 ++++++++++--------
 .../src/lib/+state/vorgang.reducer.spec.ts    |  75 ++++++++-
 .../src/lib/+state/vorgang.reducer.ts         |  27 ++++
 .../src/lib/+state/vorgang.selectors.spec.ts  | 131 +++++++---------
 .../src/lib/+state/vorgang.selectors.ts       | 117 +++++++-------
 .../src/lib/vorgang.service.spec.ts           |  99 +++++++++++-
 .../vorgang-shared/src/lib/vorgang.service.ts |  38 ++++-
 31 files changed, 853 insertions(+), 555 deletions(-)

diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts
index 7248a1727b..7a882428f3 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-mail-error.cy.ts
@@ -21,9 +21,8 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { E2EAppHelper } from 'apps/alfa-e2e/src/helper/app.helper';
 import { E2EPostfachNachrichtVerifier } from 'apps/alfa-e2e/src/helper/postfach-nachricht/postfach-nachricht.verifier';
-import { E2EVorgangNavigator } from 'apps/alfa-e2e/src/helper/vorgang/vorgang.navigator';
+import { APP_HELPER, VORGANG_NAVIGATOR } from 'apps/alfa-e2e/src/support/e2e';
 import {
   createPostfachNachrichtAttachedItem,
   createPostfachNachrichtReplyItem,
@@ -42,7 +41,7 @@ import {
   PostfachNachrichtSnackbarMessageE2E,
   VorgangAttachedItemE2E,
 } from '../../../model/vorgang-attached-item';
-import { containsSpinner, MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
+import { containsSpinner, MainPage, notContainsSpinner, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
 import { PostfachMailPage } from '../../../page-objects/postfach-mail.component.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
 import { contains, exist, notExist } from '../../../support/cypress.util';
@@ -51,9 +50,6 @@ import { initVorgangAttachedItem } from '../../../support/vorgang-attached-item-
 import { createVorgang, initVorgang, objectIds } from '../../../support/vorgang-util';
 
 describe('PostfachMail error', () => {
-  const appHelper: E2EAppHelper = new E2EAppHelper();
-  const vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator();
-
   const mainPage: MainPage = new MainPage();
   const snackbar: SnackBarE2EComponent = mainPage.getSnackBar();
 
@@ -94,12 +90,12 @@ describe('PostfachMail error', () => {
     initVorgang(vorgang);
     initVorgangAttachedItem([vorgangAttachedItem, vorgangAttachedItem2]);
 
-    appHelper.loginAsSabine();
+    APP_HELPER.loginAsSabine();
   });
 
   describe('navigate to vorgang detail', () => {
     it('should open vorgang detail', () => {
-      vorgangNavigator.openVorgang(vorgang.name);
+      VORGANG_NAVIGATOR.openVorgang(vorgang.name);
       waitForSpinnerToDisappear();
     });
 
@@ -131,6 +127,7 @@ describe('PostfachMail error', () => {
       it('click on resend button should hide error', () => {
         listItem.getResendButton().click();
         containsSpinner(listItem.getResendButton());
+        notContainsSpinner(postfachMailPage.getListItem(postfachNachricht2.subject).getResendButton());
         waitForSpinnerToDisappear();
 
         notExist(listItem.getSendErrorIcon());
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts
index d2c1d45bf3..ffcd5734aa 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-pending-send.cy.ts
@@ -1,28 +1,31 @@
 import { PostfachMailE2EComponent } from 'apps/alfa-e2e/src/components/postfach/postfach-mail.e2e.component';
-import { E2EAppHelper } from 'apps/alfa-e2e/src/helper/app.helper';
-import { E2EVorgangNavigator } from 'apps/alfa-e2e/src/helper/vorgang/vorgang.navigator';
 import { CommandE2E, CommandOrderE2E, CommandStatusE2E } from 'apps/alfa-e2e/src/model/command';
-import { createCommand, initCommand } from 'apps/alfa-e2e/src/support/command-util';
+import { createCommand, initCommands } from 'apps/alfa-e2e/src/support/command-util';
+import { APP_HELPER, VORGANG_NAVIGATOR } from 'apps/alfa-e2e/src/support/e2e';
 import {
   createPostfachNachrichtAttachedItem,
+  createPostfachNachrichtReplyItem,
   createSendPostfachNachrichtItem,
 } from 'apps/alfa-e2e/src/support/postfach-nachricht.util';
+import { getUserSabineId } from 'apps/alfa-e2e/src/support/user-util';
 import { initVorgangAttachedItem } from 'apps/alfa-e2e/src/support/vorgang-attached-item-util';
 import { VorgangE2E } from '../../../model/vorgang';
-import { PostfachMailItemE2E, VorgangAttachedItemE2E } from '../../../model/vorgang-attached-item';
+import {
+  DirectionE2E,
+  PostfachMailItemE2E,
+  PostfachNachrichtMessageCodeE2E,
+  VorgangAttachedItemE2E,
+} from '../../../model/vorgang-attached-item';
 import { containsSpinner } from '../../../page-objects/main.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
 import { exist } from '../../../support/cypress.util';
-import { createVorgang, initVorgang, objectIds } from '../../../support/vorgang-util';
-
-describe('Postfach Nachricht pending send', () => {
-  const appHelper: E2EAppHelper = new E2EAppHelper();
-
-  const vorgangNavigator: E2EVorgangNavigator = new E2EVorgangNavigator();
+import { buildVorgang, createVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util';
 
+describe('Postfach Nachricht pending', () => {
   const vorgangPage: VorgangPage = new VorgangPage();
   const postfachMailContainer: PostfachMailE2EComponent = vorgangPage.getPostfachMailcontainer();
 
+  //SEND
   const vorgangWithPendingSendCommand: VorgangE2E = { ...createVorgang(), name: 'VorgangWithPendingSendCommand' };
   const postfachSendNachrichtItem: PostfachMailItemE2E = {
     ...createSendPostfachNachrichtItem(),
@@ -40,17 +43,63 @@ describe('Postfach Nachricht pending send', () => {
     body: postfachSendNachrichtItem,
   };
 
+  //RESEND 1
+  const vorgangWithResendCommand: VorgangE2E = buildVorgang(objectIds[1], 'VorgangWithResendCommand');
+  const resendPostfachNachricht1: PostfachMailItemE2E = {
+    ...createPostfachNachrichtReplyItem(),
+    subject: 'Failed Outgoing Postfach Nachricht 1',
+    createdBy: getUserSabineId(),
+    direction: DirectionE2E.OUT,
+    sentAt: '2022-12-02T15:00:00.790Z[UTC]',
+    sentSuccessful: false,
+    messageCode: PostfachNachrichtMessageCodeE2E.PROCESSING_FAILED,
+  };
+  const resendPostfachNachrichtVorgangAttachedItem1: VorgangAttachedItemE2E = {
+    ...createPostfachNachrichtAttachedItem(objectIds[2], vorgangWithResendCommand._id.$oid),
+    item: resendPostfachNachricht1,
+  };
+  const pendingResendCommand1: CommandE2E = {
+    ...createCommand(),
+    _id: { $oid: objectIds[1] },
+    vorgangId: vorgangWithResendCommand._id.$oid,
+    order: CommandOrderE2E.RESEND_POSTFACH_NACHRICHT,
+    status: CommandStatusE2E.PENDING,
+    finishedAt: null,
+    body: resendPostfachNachricht1,
+    relationId: resendPostfachNachrichtVorgangAttachedItem1._id.$oid,
+  };
+
+  //RESEND 2
+  const resendPostfachNachricht2: PostfachMailItemE2E = {
+    ...resendPostfachNachricht1,
+    subject: 'Failed Outgoing Postfach Nachricht 2',
+  };
+  const resendPostfachNachrichtVorgangAttachedItem2: VorgangAttachedItemE2E = {
+    ...createPostfachNachrichtAttachedItem(objectIds[3], vorgangWithResendCommand._id.$oid),
+    item: resendPostfachNachricht2,
+  };
+  const pendingResendCommand2: CommandE2E = {
+    ...pendingResendCommand1,
+    _id: { $oid: objectIds[2] },
+    body: resendPostfachNachricht2,
+    relationId: resendPostfachNachrichtVorgangAttachedItem2._id.$oid,
+  };
+
   before(() => {
-    initVorgang(vorgangWithPendingSendCommand);
-    initVorgangAttachedItem([postfachNachrichtAttachedItem]);
-    initCommand(pendingSendCommand);
+    initVorgaenge([vorgangWithPendingSendCommand, vorgangWithResendCommand]);
+    initVorgangAttachedItem([
+      postfachNachrichtAttachedItem,
+      resendPostfachNachrichtVorgangAttachedItem1,
+      resendPostfachNachrichtVorgangAttachedItem2,
+    ]);
+    initCommands([pendingSendCommand, pendingResendCommand1, pendingResendCommand2]);
 
-    appHelper.loginAsSabine();
+    APP_HELPER.loginAsSabine();
   });
 
-  describe('area in vorgang detail', () => {
+  describe('send command on area in vorgang detail', () => {
     it('should have item in list', () => {
-      vorgangNavigator.openVorgang(vorgangWithPendingSendCommand.name);
+      VORGANG_NAVIGATOR.openVorgang(vorgangWithPendingSendCommand.name);
 
       exist(postfachMailContainer.getListItem(postfachSendNachrichtItem.subject).getRoot());
     });
@@ -64,4 +113,18 @@ describe('Postfach Nachricht pending send', () => {
       exist(postfachMailContainer.getListItem(postfachSendNachrichtItem.subject).getEditButton());
     });
   });
+
+  describe('resend commands area in vorgang detail', () => {
+    it('should have items in list', () => {
+      VORGANG_NAVIGATOR.openVorgang(vorgangWithResendCommand.name);
+
+      exist(postfachMailContainer.getListItem(resendPostfachNachricht1.subject).getRoot());
+      exist(postfachMailContainer.getListItem(resendPostfachNachricht2.subject).getRoot());
+    });
+
+    it('should show spinner on buttons', () => {
+      containsSpinner(postfachMailContainer.getListItem(resendPostfachNachricht1.subject).getResendButton());
+      containsSpinner(postfachMailContainer.getListItem(resendPostfachNachricht2.subject).getResendButton());
+    });
+  });
 });
diff --git a/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts b/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts
index d47b4e62dc..69da85ac92 100644
--- a/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts
+++ b/alfa-client/apps/alfa-e2e/src/page-objects/main.po.ts
@@ -111,6 +111,10 @@ export function containsSpinner(rootElement: Cypress.Chainable<JQuery<Element>>)
   exist(rootElement.findTestElementWithClass(MainPage.SPINNER));
 }
 
+export function notContainsSpinner(rootElement: Cypress.Chainable<JQuery<Element>>): void {
+  notExist(rootElement.findTestElementWithClass(MainPage.SPINNER));
+}
+
 //TODO Funktion loeschen
 export function waitforSpinnerToAppear(): void {
   // exist(cy.getTestElementWithClass('spinner'));
diff --git a/alfa-client/apps/alfa-e2e/src/support/e2e.ts b/alfa-client/apps/alfa-e2e/src/support/e2e.ts
index 6334e8ea63..0d31b33108 100644
--- a/alfa-client/apps/alfa-e2e/src/support/e2e.ts
+++ b/alfa-client/apps/alfa-e2e/src/support/e2e.ts
@@ -40,6 +40,8 @@
 import 'cypress-mochawesome-reporter/register';
 import 'cypress-real-events';
 import 'cypress-timestamps/support';
+import { E2EAppHelper } from '../helper/app.helper';
+import { E2EVorgangNavigator } from '../helper/vorgang/vorgang.navigator';
 import './commands';
 import { dropCollections } from './cypress-helper';
 import './file-upload';
@@ -73,3 +75,7 @@ after(() => {
   dropCollections();
   cy.log('...cleanup done.');
 });
+
+export const APP_HELPER: E2EAppHelper = new E2EAppHelper();
+
+export const VORGANG_NAVIGATOR: E2EVorgangNavigator = new E2EVorgangNavigator();
diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.actions.ts b/alfa-client/libs/command-shared/src/lib/+state/command.actions.ts
index e573a10f4a..e899a6df08 100644
--- a/alfa-client/libs/command-shared/src/lib/+state/command.actions.ts
+++ b/alfa-client/libs/command-shared/src/lib/+state/command.actions.ts
@@ -29,18 +29,11 @@ import {
   TypedActionCreatorWithProps,
 } from '@alfa-client/tech-shared';
 import { HttpErrorResponse } from '@angular/common/http';
-import { createAction, props, Action } from '@ngrx/store';
-import { Resource } from '@ngxp/rest';
-import {
-  CommandListResource,
-  CommandResource,
-  CreateCommand,
-  CreateCommandProps,
-} from '../command.model';
+import { Action, createAction, props } from '@ngrx/store';
+import { Resource, ResourceUri } from '@ngxp/rest';
+import { CommandListResource, CommandResource, CreateCommand, CreateCommandProps } from '../command.model';
 
-export const publishConcurrentModificationAction: TypedActionCreator = createAction(
-  '[Command/API] Concurrent Modification',
-);
+export const publishConcurrentModificationAction: TypedActionCreator = createAction('[Command/API] Concurrent Modification');
 
 export interface CommandStateResourceProps {
   commandStateResource: StateResource<CommandResource>;
@@ -52,9 +45,7 @@ export interface LoadCommandListSuccessProps {
 export interface LoadCommandListProps {
   resource: Resource;
   linkRel: string;
-  successAction: (
-    commandList: CommandListResource,
-  ) => LoadCommandListSuccessProps & Action<string>;
+  successAction: (commandList: CommandListResource) => LoadCommandListSuccessProps & Action<string>;
   failureAction: (apiError: ApiError) => ApiErrorAction & Action<string>;
 }
 
@@ -63,6 +54,11 @@ export const loadCommandList: TypedActionCreatorWithProps<LoadCommandListProps>
   props<LoadCommandListProps>(),
 );
 
+export interface UpdateCommandProps {
+  relatedResourceUri: ResourceUri;
+  command: CommandResource;
+}
+
 export interface CommandProps {
   command: CommandResource;
 }
@@ -82,7 +78,13 @@ export interface RevokeCommandFailureProps {
   error: ApiError | unknown;
 }
 
+export interface CreateCommandSuccessProps {
+  createCommandProps: CreateCommandProps;
+  command: CommandResource;
+}
+
 export interface CreateCommandFailureProps {
+  createCommandProps: CreateCommandProps;
   command: CreateCommand;
   error: ApiError | HttpErrorResponse | unknown;
 }
@@ -91,12 +93,14 @@ export const createCommand: TypedActionCreatorWithProps<CreateCommandProps> = cr
   '[Command] Create command',
   props<CreateCommandProps>(),
 );
-export const createCommandSuccess: TypedActionCreatorWithProps<CommandProps> = createAction(
+export const createCommandSuccess: TypedActionCreatorWithProps<CreateCommandSuccessProps> = createAction(
   '[Command] Create command Success',
-  props<CommandProps>(),
+  props<CreateCommandSuccessProps>(),
+);
+export const createCommandFailure: TypedActionCreatorWithProps<CreateCommandFailureProps> = createAction(
+  '[Command] Create command Failure',
+  props<CreateCommandFailureProps>(),
 );
-export const createCommandFailure: TypedActionCreatorWithProps<CreateCommandFailureProps> =
-  createAction('[Command] Create command Failure', props<CreateCommandFailureProps>());
 export const pollCreatedCommand: TypedActionCreatorWithProps<PollCommandProps> = createAction(
   '[Command] Poll created command',
   props<PollCommandProps>(),
@@ -119,8 +123,10 @@ export const revokeCommandSuccess: TypedActionCreatorWithProps<CommandProps> = c
   '[Command] Revoke command Success',
   props<CommandProps>(),
 );
-export const revokeCommandFailure: TypedActionCreatorWithProps<RevokeCommandFailureProps> =
-  createAction('[Command] Revoke command Failure', props<RevokeCommandFailureProps>());
+export const revokeCommandFailure: TypedActionCreatorWithProps<RevokeCommandFailureProps> = createAction(
+  '[Command] Revoke command Failure',
+  props<RevokeCommandFailureProps>(),
+);
 export const pollRevokedCommand: TypedActionCreatorWithProps<PollCommandProps> = createAction(
   '[Command] Poll revoked command',
   props<PollCommandProps>(),
diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts b/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts
index b1cb1673a7..1b2da80853 100644
--- a/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/+state/command.effects.spec.ts
@@ -21,12 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import {
-  ApiError,
-  ApiErrorAction,
-  EMPTY_STRING,
-  TypedActionCreatorWithProps,
-} from '@alfa-client/tech-shared';
+import { ApiError, ApiErrorAction, EMPTY_STRING, TypedActionCreatorWithProps } from '@alfa-client/tech-shared';
 import { Mock, mock } from '@alfa-client/test-utils';
 import { SnackBarService } from '@alfa-client/ui';
 import { TestBed } from '@angular/core/testing';
@@ -36,11 +31,7 @@ import { provideMockStore } from '@ngrx/store/testing';
 import { Resource } from '@ngxp/rest';
 import { cold, hot } from 'jest-marbles';
 import { ColdObservable } from 'jest-marbles/typings/src/rxjs/cold-observable';
-import {
-  createCommandListResource,
-  createCommandResource,
-  createCreateCommandProps,
-} from 'libs/command-shared/test/command';
+import { createCommandListResource, createCommandResource, createCreateCommandProps } from 'libs/command-shared/test/command';
 import { createApiError } from 'libs/tech-shared/test/error';
 import { Observable, of } from 'rxjs';
 import { TestScheduler } from 'rxjs/testing';
@@ -48,12 +39,7 @@ import { CommandLinkRel } from '../command.linkrel';
 import { CREATE_COMMAND_MESSAGE_BY_ORDER, CommandErrorMessage } from '../command.message';
 import { CommandListResource, CommandResource, CreateCommandProps } from '../command.model';
 import { CommandRepository } from '../command.repository';
-import {
-  CommandProps,
-  LoadCommandListSuccessProps,
-  SnackBarProps,
-  createCommandFailure,
-} from './command.actions';
+import { CommandProps, LoadCommandListSuccessProps, SnackBarProps, createCommandFailure } from './command.actions';
 import { CommandEffects } from './command.effects';
 
 import * as CommandActions from './command.actions';
@@ -121,7 +107,7 @@ describe('CommandEffects', () => {
     const commandListResource: CommandListResource = createCommandListResource();
 
     beforeEach(() => {
-      repository.getPendingCommands.mockReturnValue(of(commandListResource));
+      repository.getCommands.mockReturnValue(of(commandListResource));
     });
 
     it('should call repository', () => {
@@ -129,7 +115,7 @@ describe('CommandEffects', () => {
 
       effects.loadCommandList$.subscribe();
 
-      expect(repository.getPendingCommands).toHaveBeenCalledWith(resource, linkRel);
+      expect(repository.getCommands).toHaveBeenCalledWith(resource, linkRel);
     });
 
     it('should dispatch success action on no error', () => {
@@ -145,7 +131,7 @@ describe('CommandEffects', () => {
       const apiError: ApiError = createApiError();
       const error = { error: apiError };
       const errorResponse = cold('-#', {}, error);
-      repository.getPendingCommands = jest.fn(() => errorResponse);
+      repository.getCommands = jest.fn(() => errorResponse);
 
       actions = hot('-a', { a: loadCommandList });
 
@@ -156,8 +142,7 @@ describe('CommandEffects', () => {
 
   describe('createCommand', () => {
     const createCommandProps: CreateCommandProps = createCreateCommandProps();
-    const createCommandAction: Action<string> =
-      CommandActions.createCommand(createCommandProps);
+    const createCommandAction: Action<string> = CommandActions.createCommand(createCommandProps);
 
     const commandResource: CommandResource = createCommandResource();
 
@@ -184,10 +169,7 @@ describe('CommandEffects', () => {
 
       effects.createCommand$.subscribe();
 
-      expect(effects.handleCreatedCommand).toHaveBeenCalledWith(
-        addCreateCommandActionType(createCommandProps),
-        commandResource,
-      );
+      expect(effects.handleCreatedCommand).toHaveBeenCalledWith(addCreateCommandActionType(createCommandProps), commandResource);
     });
 
     function addCreateCommandActionType(createCommandProps: CreateCommandProps) {
@@ -202,7 +184,11 @@ describe('CommandEffects', () => {
       actions = hot('-a', { a: createCommandAction });
 
       const expected: ColdObservable = cold('--b', {
-        b: CommandActions.createCommandFailure({ error, command: createCommandProps.command }),
+        b: CommandActions.createCommandFailure({
+          createCommandProps: addCreateCommandActionType(createCommandProps),
+          error,
+          command: createCommandProps.command,
+        }),
       });
       expect(effects.createCommand$).toBeObservable(expected);
     });
@@ -214,10 +200,7 @@ describe('CommandEffects', () => {
     it('should return pollCreatedCommand action on pending command', () => {
       const command: CommandResource = createCommandResource([CommandLinkRel.UPDATE]);
 
-      const actions: Action<string>[] = effects.handleCreatedCommand(
-        createCommandProps,
-        command,
-      );
+      const actions: Action<string>[] = effects.handleCreatedCommand(createCommandProps, command);
 
       expect(actions.length).toBe(1);
       expect(actions[0].type).toBe(CommandActions.pollCreatedCommand.type);
@@ -285,7 +268,7 @@ describe('CommandEffects', () => {
         actions = hot('-a', { a: pollCreateCommandAction });
 
         expectObservable(effects.pollCreatedCommand$).toBe(delay + ' --c', {
-          c: createCommandFailure({ command, error }),
+          c: createCommandFailure({ createCommandProps: null, command, error }),
         });
       });
     });
@@ -298,10 +281,7 @@ describe('CommandEffects', () => {
       it('should return createCommandSuccess action', () => {
         const command: CommandResource = createCommandResource();
 
-        const actions: Action<string>[] = effects.handleCreateCommandSuccess(
-          createCommandProps,
-          command,
-        );
+        const actions: Action<string>[] = effects.handleCreateCommandSuccess(createCommandProps, command);
 
         expect(actions.length).toBe(2);
         const createCommandSuccessAction: CommandActions.CommandProps = <any>actions[0];
@@ -312,10 +292,7 @@ describe('CommandEffects', () => {
       it('should return showSnackbar action', () => {
         const command: CommandResource = createCommandResource();
 
-        const actions: Action<string>[] = effects.handleCreateCommandSuccess(
-          createCommandProps,
-          command,
-        );
+        const actions: Action<string>[] = effects.handleCreateCommandSuccess(createCommandProps, command);
 
         expect(actions.length).toBe(2);
         const showSnackbarAction: CommandActions.SnackBarProps = <any>actions[1];
@@ -328,10 +305,7 @@ describe('CommandEffects', () => {
       it('should return createCommandSuccess action', () => {
         const command: CommandResource = createCommandResource([CommandLinkRel.REVOKE]);
 
-        const actions: Action<string>[] = effects.handleCreateCommandSuccess(
-          createCommandProps,
-          command,
-        );
+        const actions: Action<string>[] = effects.handleCreateCommandSuccess(createCommandProps, command);
 
         expect(actions.length).toBe(2);
         expect(actions[0].type).toBe(CommandActions.createCommandSuccess.type);
@@ -341,10 +315,7 @@ describe('CommandEffects', () => {
       it('should return showRevokeSnackbar action', () => {
         const command: CommandResource = createCommandResource([CommandLinkRel.REVOKE]);
 
-        const actions: Action<string>[] = effects.handleCreateCommandSuccess(
-          createCommandProps,
-          command,
-        );
+        const actions: Action<string>[] = effects.handleCreateCommandSuccess(createCommandProps, command);
 
         expect(actions.length).toBe(2);
         expect(actions[1].type).toBe(CommandActions.showRevokeSnackbar.type);
@@ -372,10 +343,7 @@ describe('CommandEffects', () => {
           errorMessage: CommandErrorMessage.CONCURRENT_MODIFICATION,
         };
 
-        const actions: Action<string>[] = effects.handleCreateCommandSuccess(
-          createCommandProps,
-          command,
-        );
+        const actions: Action<string>[] = effects.handleCreateCommandSuccess(createCommandProps, command);
 
         expect(actions.length).toBe(2);
         expect(actions[0].type).toBe(CommandActions.createCommandSuccess.type);
@@ -428,10 +396,7 @@ describe('CommandEffects', () => {
 
       effects.handleSnackbarByCommand(snackBarProps);
 
-      expect(snackBarService.show).toHaveBeenCalledWith(
-        command,
-        createCommandProps.snackBarMessage,
-      );
+      expect(snackBarService.show).toHaveBeenCalledWith(command, createCommandProps.snackBarMessage);
     });
 
     it('should show snackBar on undefined snackBarMessage', () => {
@@ -442,10 +407,7 @@ describe('CommandEffects', () => {
 
       effects.handleSnackbarByCommand(snackBarProps);
 
-      expect(snackBarService.show).toHaveBeenCalledWith(
-        command,
-        CREATE_COMMAND_MESSAGE_BY_ORDER[command.order],
-      );
+      expect(snackBarService.show).toHaveBeenCalledWith(command, CREATE_COMMAND_MESSAGE_BY_ORDER[command.order]);
     });
 
     it('should NOT show snackBar on empty snackBarMessage', () => {
diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts b/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts
index 6b13e23b3f..3df93f0045 100644
--- a/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts
+++ b/alfa-client/libs/command-shared/src/lib/+state/command.effects.ts
@@ -25,19 +25,14 @@ import { EMPTY_STRING } from '@alfa-client/tech-shared';
 import { SnackBarService } from '@alfa-client/ui';
 import { Injectable } from '@angular/core';
 import { Actions, createEffect, ofType } from '@ngrx/effects';
-import { Store, Action } from '@ngrx/store';
+import { Action, Store } from '@ngrx/store';
 import { isEmpty, isEqual, isUndefined } from 'lodash-es';
 import { of } from 'rxjs';
 import { catchError, delay, map, mergeMap, switchMap, tap } from 'rxjs/operators';
 import { COMMAND_ERROR_MESSAGES, CREATE_COMMAND_MESSAGE_BY_ORDER } from '../command.message';
 import { CommandListResource, CommandResource, CreateCommandProps } from '../command.model';
 import { CommandRepository } from '../command.repository';
-import {
-  hasCommandError,
-  isConcurrentModification,
-  isPending,
-  isRevokeable,
-} from '../command.util';
+import { hasCommandError, isConcurrentModification, isPending, isRevokeable } from '../command.util';
 import {
   CommandProps,
   LoadCommandListProps,
@@ -72,7 +67,7 @@ export class CommandEffects {
     this.actions$.pipe(
       ofType(loadCommandList),
       switchMap((props: LoadCommandListProps) =>
-        this.repository.getPendingCommands(props.resource, props.linkRel).pipe(
+        this.repository.getCommands(props.resource, props.linkRel).pipe(
           map((commandList: CommandListResource) => props.successAction(commandList)),
           catchError((error) => of(props.failureAction(error.error))),
         ),
@@ -86,7 +81,7 @@ export class CommandEffects {
       switchMap((props: CreateCommandProps) =>
         this.repository.createCommand(props.resource, props.linkRel, props.command).pipe(
           mergeMap((command: CommandResource) => this.handleCreatedCommand(props, command)),
-          catchError((error) => of(createCommandFailure({ error, command: props.command }))),
+          catchError((error) => of(createCommandFailure({ createCommandProps: props, error, command: props.command }))),
         ),
       ),
     ),
@@ -98,39 +93,34 @@ export class CommandEffects {
       delay(CommandEffects.POLL_DELAY),
       switchMap((props: PollCommandProps) =>
         this.repository.getCommand(props.command).pipe(
-          mergeMap((command: CommandResource) =>
-            this.handleCreatedCommand(props.createCommandProps, command),
+          mergeMap((command: CommandResource) => this.handleCreatedCommand(props.createCommandProps, command)),
+          catchError((error) =>
+            of(createCommandFailure({ createCommandProps: props.createCommandProps, command: props.command, error })),
           ),
-          catchError((error) => of(createCommandFailure({ command: props.command, error }))),
         ),
       ),
     ),
   );
 
-  handleCreatedCommand(
-    createCommandProps: CreateCommandProps,
-    command: CommandResource,
-  ): Action<string>[] {
+  handleCreatedCommand(createCommandProps: CreateCommandProps, command: CommandResource): Action<string>[] {
     if (isPending(command)) {
       return [pollCreatedCommand({ createCommandProps, command })];
     }
     return this.handleCreateCommandSuccess(createCommandProps, command);
   }
 
-  handleCreateCommandSuccess(
-    createCommandProps: CreateCommandProps,
-    command: CommandResource,
-  ): Action<string>[] {
+  handleCreateCommandSuccess(createCommandProps: CreateCommandProps, command: CommandResource): Action<string>[] {
     if (isRevokeable(command)) {
-      return [createCommandSuccess({ command }), showRevokeSnackbar({ command })];
+      return [createCommandSuccess({ createCommandProps, command }), showRevokeSnackbar({ command })];
     }
+
     if (hasCommandError(command) && isConcurrentModification(command.errorMessage)) {
       this.showError(command);
       //FIXME Anstelle der createCommandSucess Action sollte eine createCommandFailure Action geworfen werden.
       //Hierzu muss ein HttpErrorResponse für die errorMessage definieren werden
-      return [createCommandSuccess({ command }), publishConcurrentModificationAction()];
+      return [createCommandSuccess({ createCommandProps, command }), publishConcurrentModificationAction()];
     }
-    return [createCommandSuccess({ command }), showSnackbar({ createCommandProps, command })];
+    return [createCommandSuccess({ createCommandProps, command }), showSnackbar({ createCommandProps, command })];
   }
 
   private showError(command: CommandResource): void {
@@ -166,10 +156,7 @@ export class CommandEffects {
   );
 
   handleSnackbarByCommand(props: SnackBarProps): void {
-    if (
-      !isEqual(props.createCommandProps.snackBarMessage, EMPTY_STRING) &&
-      isEmpty(props.command.errorMessage)
-    ) {
+    if (!isEqual(props.createCommandProps.snackBarMessage, EMPTY_STRING) && isEmpty(props.command.errorMessage)) {
       this.snackbarService.show(props.command, this.getSnackBarMessage(props));
     }
   }
diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.reducer.spec.ts b/alfa-client/libs/command-shared/src/lib/+state/command.reducer.spec.ts
index 9a3735965f..161bddb678 100644
--- a/alfa-client/libs/command-shared/src/lib/+state/command.reducer.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/+state/command.reducer.spec.ts
@@ -26,21 +26,27 @@ import {
   createEmptyStateResource,
   createErrorStateResource,
   createStateResource,
+  LinkRelationName,
 } from '@alfa-client/tech-shared';
 import { HttpErrorResponse } from '@angular/common/http';
+import { faker } from '@faker-js/faker';
 import { Action } from '@ngrx/store';
-import { Resource, ResourceUri } from '@ngxp/rest';
+import { getUrl, Resource, ResourceUri } from '@ngxp/rest';
 import { createApiError, createHttpErrorResponse } from '../../../../tech-shared/test/error';
 import { createDummyResource } from '../../../../tech-shared/test/resource';
-import { createCommandResource, createCreateCommand } from '../../../test/command';
-import { CommandResource, CreateCommand } from '../command.model';
-import { CommandState, initialState, reducer } from './command.reducer';
-
-import { faker } from '@faker-js/faker';
+import { createCommandResource, createCreateCommand, createCreateCommandProps } from '../../../test/command';
+import { CommandResource, CreateCommand, CreateCommandProps } from '../command.model';
+import { buildCommandStateKey, CommandState, initialState, reducer } from './command.reducer';
 
 import * as CommandActions from '../+state/command.actions';
 
 describe('Command Reducer', () => {
+  const linkRel: LinkRelationName = faker.string.alpha(6);
+  const resource: Resource = createDummyResource([linkRel]);
+  const uri: ResourceUri = getUrl(resource, linkRel);
+  const commandResource: CommandResource = createCommandResource();
+  const createCommandProps: CreateCommandProps = { ...createCreateCommandProps(), resource, linkRel };
+
   describe('unknown action', () => {
     it('should return current state', () => {
       const action: Action = {} as Action;
@@ -52,42 +58,48 @@ describe('Command Reducer', () => {
   });
 
   describe('createCommand', () => {
-    const resource: Resource = createDummyResource();
-    const linkRel: ResourceUri = faker.internet.url();
     const command: CreateCommand = createCreateCommand();
 
     it('should create empty loading map entry', () => {
-      const action = CommandActions.createCommand({ resource, linkRel, command });
+      const action: Action<string> = CommandActions.createCommand({ resource, linkRel, command });
 
       const state: CommandState = reducer(initialState, action);
 
-      expect(state.commandByOrderMap[command.order]).toEqual(createEmptyStateResource(true));
+      expect(state.commandMap[buildCommandStateKey(command.order, uri)]).toEqual(createEmptyStateResource(true));
     });
   });
 
   describe('createCommandSuccess', () => {
-    const command: CommandResource = createCommandResource();
-
     it('should create stateResource entry by loaded resource', () => {
-      const action = CommandActions.createCommandSuccess({ command });
+      const action: Action<string> = CommandActions.createCommandSuccess({
+        createCommandProps,
+        command: commandResource,
+      });
 
       const state: CommandState = reducer(initialState, action);
 
-      expect(state.commandByOrderMap[command.order]).toEqual(createStateResource(command));
+      expect(state.commandMap[buildCommandStateKey(createCommandProps.command.order, uri)]).toEqual(
+        createStateResource(commandResource),
+      );
     });
   });
 
   describe('createCommandFailure', () => {
-    const command: CommandResource = createCommandResource();
     const error: ApiError = createApiError();
     const httpErrorResponse: HttpErrorResponse = { ...createHttpErrorResponse(), error };
 
     it('should create errorStateResource entry by occured error', () => {
-      const action = CommandActions.createCommandFailure({ command, error: httpErrorResponse });
+      const action: Action<string> = CommandActions.createCommandFailure({
+        createCommandProps,
+        command: commandResource,
+        error: httpErrorResponse,
+      });
 
       const state: CommandState = reducer(initialState, action);
 
-      expect(state.commandByOrderMap[command.order]).toEqual(createErrorStateResource(error));
+      expect(state.commandMap[buildCommandStateKey(createCommandProps.command.order, uri)]).toEqual(
+        createErrorStateResource(error),
+      );
     });
   });
 });
diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.reducer.ts b/alfa-client/libs/command-shared/src/lib/+state/command.reducer.ts
index bce701b1df..3c9e84e51d 100644
--- a/alfa-client/libs/command-shared/src/lib/+state/command.reducer.ts
+++ b/alfa-client/libs/command-shared/src/lib/+state/command.reducer.ts
@@ -21,16 +21,13 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import {
-  StateResource,
-  createEmptyStateResource,
-  createErrorStateResource,
-  createStateResource,
-} from '@alfa-client/tech-shared';
+import { createEmptyStateResource, createErrorStateResource, createStateResource, StateResource } from '@alfa-client/tech-shared';
+import { HttpErrorResponse } from '@angular/common/http';
 import { Action, ActionReducer, createReducer, on } from '@ngrx/store';
-import { CommandResource, CreateCommandProps } from '../command.model';
+import { getUrl, ResourceUri } from '@ngxp/rest';
+import { CommandOrder, CommandResource, CreateCommandProps } from '../command.model';
+import { CreateCommandFailureProps, CreateCommandSuccessProps } from './command.actions';
 
-import { HttpErrorResponse } from '@angular/common/http';
 import * as Actions from './command.actions';
 
 export const COMMAND_FEATURE_KEY = 'CommandState';
@@ -40,11 +37,11 @@ export interface CommandPartialState {
 }
 
 export interface CommandState {
-  commandByOrderMap: { [order: string]: StateResource<CommandResource> };
+  commandMap: { [key: string]: StateResource<CommandResource> };
 }
 
 export const initialState: CommandState = {
-  commandByOrderMap: {},
+  commandMap: {},
 };
 
 const commandReducer: ActionReducer<CommandState, Action> = createReducer(
@@ -53,29 +50,29 @@ const commandReducer: ActionReducer<CommandState, Action> = createReducer(
     Actions.createCommand,
     (state: CommandState, props: CreateCommandProps): CommandState => ({
       ...state,
-      commandByOrderMap: {
-        ...state.commandByOrderMap,
-        [props.command.order]: createEmptyStateResource(true),
+      commandMap: {
+        ...state.commandMap,
+        [createCommandStateKey(props)]: createEmptyStateResource(true),
       },
     }),
   ),
   on(
     Actions.createCommandSuccess,
-    (state: CommandState, props: Actions.CommandProps): CommandState => ({
+    (state: CommandState, props: CreateCommandSuccessProps): CommandState => ({
       ...state,
-      commandByOrderMap: {
-        ...state.commandByOrderMap,
-        [props.command.order]: createStateResource(props.command),
+      commandMap: {
+        ...state.commandMap,
+        [createCommandStateKey(props.createCommandProps)]: createStateResource(props.command),
       },
     }),
   ),
   on(
     Actions.createCommandFailure,
-    (state: CommandState, props: Actions.CreateCommandFailureProps): CommandState => ({
+    (state: CommandState, props: CreateCommandFailureProps): CommandState => ({
       ...state,
-      commandByOrderMap: {
-        ...state.commandByOrderMap,
-        [props.command.order]: createErrorStateResource((<HttpErrorResponse>props.error).error),
+      commandMap: {
+        ...state.commandMap,
+        [createCommandStateKey(props.createCommandProps)]: createErrorStateResource((<HttpErrorResponse>props.error).error),
       },
     }),
   ),
@@ -84,3 +81,11 @@ const commandReducer: ActionReducer<CommandState, Action> = createReducer(
 export function reducer(state: CommandState, action: Action): CommandState {
   return commandReducer(state, action);
 }
+
+function createCommandStateKey(props: CreateCommandProps): string {
+  return buildCommandStateKey(props.command.order, getUrl(props.resource, props.linkRel));
+}
+
+export function buildCommandStateKey(order: CommandOrder, uri: ResourceUri): string {
+  return `${order}_${uri}`;
+}
diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.selectors.spec.ts b/alfa-client/libs/command-shared/src/lib/+state/command.selectors.spec.ts
index cc0f81f2f5..d2e786a6f8 100644
--- a/alfa-client/libs/command-shared/src/lib/+state/command.selectors.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/+state/command.selectors.spec.ts
@@ -21,10 +21,12 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { StateResource, createEmptyStateResource } from '@alfa-client/tech-shared';
+import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared';
+import { faker } from '@faker-js/faker/.';
+import { ResourceUri } from '@ngxp/rest';
 import { createCreateCommand } from 'libs/command-shared/test/command';
 import { CommandOrder, CommandResource, CreateCommand } from '../command.model';
-import { CommandPartialState, initialState } from './command.reducer';
+import { buildCommandStateKey, CommandPartialState, initialState } from './command.reducer';
 
 import * as Selectors from './command.selectors';
 
@@ -32,38 +34,37 @@ describe('Command Selectors', () => {
   let state: CommandPartialState;
 
   const commandInState: CreateCommand = createCreateCommand();
+  const uri: ResourceUri = faker.internet.url();
+
   const commandInStateOrder: CommandOrder = CommandOrder.VORGANG_ANNEHMEN;
-  const commandByOrderMap: any = { [commandInStateOrder]: commandInState };
+  const commandMap: any = { [buildCommandStateKey(commandInStateOrder, uri)]: commandInState };
 
   beforeEach(() => {
     state = {
       CommandState: {
         ...initialState,
-        commandByOrderMap,
+        commandMap,
       },
     };
   });
 
-  describe('commandByOrderMap', () => {
-    it('should select commandByOrderMap', () => {
-      const result: any = Selectors.commandByOrderMap.projector(state.CommandState);
+  describe('commandMap', () => {
+    it('should select commandMap', () => {
+      const result: any = Selectors.commandMap.projector(state.CommandState);
 
-      expect(result).toBe(commandByOrderMap);
+      expect(result).toBe(commandMap);
     });
   });
 
-  describe('commandByOrder', () => {
+  describe('command', () => {
     it('should return command from map by order', () => {
-      const result: StateResource<CommandResource> =
-        Selectors.commandByOrder(commandInStateOrder).projector(commandByOrderMap);
+      const result: StateResource<CommandResource> = Selectors.command(commandInStateOrder, uri).projector(commandMap);
 
       expect(result).toBe(commandInState);
     });
 
     it('should return empty state resource on empty object', () => {
-      const result: StateResource<CommandResource> = Selectors.commandByOrder(
-        commandInStateOrder,
-      ).projector({});
+      const result: StateResource<CommandResource> = Selectors.command(commandInStateOrder, uri).projector({});
 
       expect(result).toEqual(createEmptyStateResource());
     });
diff --git a/alfa-client/libs/command-shared/src/lib/+state/command.selectors.ts b/alfa-client/libs/command-shared/src/lib/+state/command.selectors.ts
index db561e1aec..2e31f077a0 100644
--- a/alfa-client/libs/command-shared/src/lib/+state/command.selectors.ts
+++ b/alfa-client/libs/command-shared/src/lib/+state/command.selectors.ts
@@ -22,21 +22,21 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import { createEmptyStateResource } from '@alfa-client/tech-shared';
-import { MemoizedSelector, createFeatureSelector, createSelector } from '@ngrx/store';
+import { createFeatureSelector, createSelector, MemoizedSelector } from '@ngrx/store';
+import { ResourceUri } from '@ngxp/rest';
 import { isUndefined } from 'lodash-es';
 import { CommandOrder } from '../command.model';
-import { COMMAND_FEATURE_KEY, CommandState } from './command.reducer';
+import { buildCommandStateKey, COMMAND_FEATURE_KEY, CommandState } from './command.reducer';
 
-const getCommandState: MemoizedSelector<object, CommandState> =
-  createFeatureSelector<CommandState>(COMMAND_FEATURE_KEY);
+const getCommandState: MemoizedSelector<object, CommandState> = createFeatureSelector<CommandState>(COMMAND_FEATURE_KEY);
 
-export const commandByOrderMap: MemoizedSelector<CommandState, any> = createSelector(
+export const commandMap: MemoizedSelector<CommandState, any> = createSelector(
   getCommandState,
-  (state: CommandState) => state.commandByOrderMap,
+  (state: CommandState) => state.commandMap,
 );
-export const commandByOrder = (order: CommandOrder) =>
-  createSelector(commandByOrderMap, (commandByOrderMapInState: any) =>
-    isUndefined(commandByOrderMapInState[order]) ?
-      createEmptyStateResource()
-    : commandByOrderMapInState[order],
+export const command = (order: CommandOrder, uri: ResourceUri) =>
+  createSelector(commandMap, (commandMapInState: any) =>
+    isUndefined(commandMapInState[buildCommandStateKey(order, uri)]) ? createEmptyStateResource() : (
+      commandMapInState[buildCommandStateKey(order, uri)]
+    ),
   );
diff --git a/alfa-client/libs/command-shared/src/lib/command.linkrel.ts b/alfa-client/libs/command-shared/src/lib/command.linkrel.ts
index 2b92fb7620..5ef51639ba 100644
--- a/alfa-client/libs/command-shared/src/lib/command.linkrel.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.linkrel.ts
@@ -24,6 +24,7 @@
 export enum CommandLinkRel {
   CREATED_BY = 'createdBy',
   EFFECTED_RESOURCE = 'effected_resource',
+  RELATED_RESOURCE = 'related_resource',
   REVOKE = 'revoke',
   SELF = 'self',
   UPDATE = 'update',
diff --git a/alfa-client/libs/command-shared/src/lib/command.model.ts b/alfa-client/libs/command-shared/src/lib/command.model.ts
index b86ac920fb..cc598f0540 100644
--- a/alfa-client/libs/command-shared/src/lib/command.model.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.model.ts
@@ -21,7 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { ListResource } from '@alfa-client/tech-shared';
+import { ListResource, StateResource } from '@alfa-client/tech-shared';
 import { Resource } from '@ngxp/rest';
 
 export interface CreateCommand {
@@ -101,3 +101,7 @@ export interface CreateCommandProps {
 }
 
 export type CreateCommandPropsWithoutResource = Omit<CreateCommandProps, 'resource'>;
+
+export interface PendingCommandMap {
+  [relatedResourceUri: string]: StateResource<CommandResource>;
+}
diff --git a/alfa-client/libs/command-shared/src/lib/command.repository.spec.ts b/alfa-client/libs/command-shared/src/lib/command.repository.spec.ts
index 2d422eba29..c4cd71b0c6 100644
--- a/alfa-client/libs/command-shared/src/lib/command.repository.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.repository.spec.ts
@@ -21,15 +21,12 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { faker } from '@faker-js/faker';
+import { LinkRelationName } from '@alfa-client/tech-shared';
 import { mock, useFromMock } from '@alfa-client/test-utils';
+import { faker } from '@faker-js/faker';
 import { Resource, ResourceFactory } from '@ngxp/rest';
 import { cold, hot } from 'jest-marbles';
-import {
-  createCommand,
-  createCommandListResource,
-  createCommandResource,
-} from 'libs/command-shared/test/command';
+import { createCommand, createCommandListResource, createCommandResource } from 'libs/command-shared/test/command';
 import { toResource } from 'libs/tech-shared/test/resource';
 import { CommandLinkRel } from './command.linkrel';
 import { Command, CommandListResource, CommandResource, CommandStatus } from './command.model';
@@ -41,11 +38,10 @@ describe('CommandRepository', () => {
   let resourceWrapper = { post: jest.fn(), get: jest.fn(), patch: jest.fn() };
 
   const command: Command = createCommand();
-  const commandResource: CommandResource = createCommandResource();
+
+  const linkRel: LinkRelationName = 'dummyLinkRel';
+  const commandResource: CommandResource = createCommandResource([linkRel]);
   const commandListResource: CommandListResource = createCommandListResource();
-  const commandResourceWithPendingCommand: CommandResource = createCommandResource([
-    'pendingCommands',
-  ]);
 
   beforeEach(() => {
     repository = new CommandRepository(useFromMock(resourceFactory));
@@ -131,27 +127,25 @@ describe('CommandRepository', () => {
     });
   });
 
-  describe('get pending commands', () => {
-    const linkRel = 'pendingCommands';
-
+  describe('get commands', () => {
     beforeEach(() => {
       resourceWrapper.get.mockReturnValue(hot('a', { a: commandListResource }));
     });
 
     it('should call resourceFactory with resource', () => {
-      repository.getPendingCommands(commandResourceWithPendingCommand, linkRel);
+      repository.getCommands(commandResource, linkRel);
 
-      expect(resourceFactory.from).toHaveBeenCalledWith(commandResourceWithPendingCommand);
+      expect(resourceFactory.from).toHaveBeenCalledWith(commandResource);
     });
 
     it('should call resourceWrapper with linkRel', () => {
-      repository.getPendingCommands(commandResourceWithPendingCommand, linkRel);
+      repository.getCommands(commandResource, linkRel);
 
       expect(resourceWrapper.get).toHaveBeenCalledWith(linkRel);
     });
 
     it('should return value', () => {
-      const result = repository.getPendingCommands(commandResourceWithPendingCommand, linkRel);
+      const result = repository.getCommands(commandResource, linkRel);
 
       expect(result).toBeObservable(cold('a', { a: commandListResource }));
     });
diff --git a/alfa-client/libs/command-shared/src/lib/command.repository.ts b/alfa-client/libs/command-shared/src/lib/command.repository.ts
index 88f4ac7457..83c5ec53fc 100644
--- a/alfa-client/libs/command-shared/src/lib/command.repository.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.repository.ts
@@ -25,22 +25,13 @@ import { Injectable } from '@angular/core';
 import { Resource, ResourceFactory } from '@ngxp/rest';
 import { Observable } from 'rxjs';
 import { CommandLinkRel } from './command.linkrel';
-import {
-  CommandListResource,
-  CommandResource,
-  CommandStatus,
-  CreateCommand,
-} from './command.model';
+import { CommandListResource, CommandResource, CommandStatus, CreateCommand } from './command.model';
 
 @Injectable({ providedIn: 'root' })
 export class CommandRepository {
   constructor(private resourceFactory: ResourceFactory) {}
 
-  public createCommand(
-    resource: Resource,
-    linkrel: string,
-    command: CreateCommand,
-  ): Observable<CommandResource> {
+  public createCommand(resource: Resource, linkrel: string, command: CreateCommand): Observable<CommandResource> {
     return this.resourceFactory.from(resource).post(linkrel, command);
   }
 
@@ -48,14 +39,12 @@ export class CommandRepository {
     return this.resourceFactory.from(resource).get(CommandLinkRel.SELF);
   }
 
-  public getPendingCommands(resource: Resource, linkRel: string): Observable<CommandListResource> {
+  public getCommands(resource: Resource, linkRel: string): Observable<CommandListResource> {
     return this.resourceFactory.from(resource).get(linkRel);
   }
 
   public revokeCommand(resource: CommandResource): Observable<CommandResource> {
-    return this.resourceFactory
-      .from(resource)
-      .patch(CommandLinkRel.REVOKE, { status: CommandStatus.REVOKED });
+    return this.resourceFactory.from(resource).patch(CommandLinkRel.REVOKE, { status: CommandStatus.REVOKED });
   }
 
   public getEffectedResource<T>(command: CommandResource): Observable<T> {
diff --git a/alfa-client/libs/command-shared/src/lib/command.service.spec.ts b/alfa-client/libs/command-shared/src/lib/command.service.spec.ts
index 4de92f2b51..44237dadab 100644
--- a/alfa-client/libs/command-shared/src/lib/command.service.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.service.spec.ts
@@ -22,6 +22,7 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import {
+  LinkRelationName,
   StateResource,
   createEmptyStateResource,
   createErrorStateResource,
@@ -32,7 +33,7 @@ import { SnackBarService } from '@alfa-client/ui';
 import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
 import { faker } from '@faker-js/faker';
 import { Store } from '@ngrx/store';
-import { Resource } from '@ngxp/rest';
+import { Resource, ResourceUri, getUrl } from '@ngxp/rest';
 import { cold, hot } from 'jest-marbles';
 import {
   createCommand,
@@ -42,23 +43,13 @@ import {
   createCreateCommandProps,
 } from 'libs/command-shared/test/command';
 import { createHttpErrorResponse } from 'libs/tech-shared/test/http';
-import { toResource } from 'libs/tech-shared/test/resource';
+import { createDummyResource, toResource } from 'libs/tech-shared/test/resource';
 import { Observable, Subject, of, throwError } from 'rxjs';
 import { CommandLinkRel } from './command.linkrel';
 import { CommandErrorMessage } from './command.message';
-import {
-  Command,
-  CommandListResource,
-  CommandOrder,
-  CommandResource,
-  CreateCommandProps,
-} from './command.model';
+import { Command, CommandListResource, CommandOrder, CommandResource, CreateCommandProps } from './command.model';
 import { CommandRepository } from './command.repository';
-import {
-  CommandService,
-  IntervallHandleWithTickObservable,
-  startInterval,
-} from './command.service';
+import { CommandService, IntervallHandleWithTickObservable, startInterval } from './command.service';
 
 import * as Actions from './+state/command.actions';
 import * as Selectors from './+state/command.selectors';
@@ -76,9 +67,7 @@ describe('CommandService', () => {
   const commandResource: CommandResource = createCommandResource();
   const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource);
 
-  const commandResourceWithUpdateLink: CommandResource = createCommandResource([
-    CommandLinkRel.UPDATE,
-  ]);
+  const commandResourceWithUpdateLink: CommandResource = createCommandResource([CommandLinkRel.UPDATE]);
 
   beforeEach(() => {
     store = mock(Store);
@@ -87,11 +76,7 @@ describe('CommandService', () => {
     store.dispatch = jest.fn();
 
     repository = mock(CommandRepository);
-    service = new CommandService(
-      useFromMock(repository),
-      useFromMock(snackbarService),
-      useFromMock(<any>store),
-    );
+    service = new CommandService(useFromMock(repository), useFromMock(snackbarService), useFromMock(<any>store));
   });
 
   describe('create command', () => {
@@ -162,17 +147,13 @@ describe('CommandService', () => {
       beforeEach(() => {
         repository.revokeCommand.mockReturnValue(cold('a', { a: commandResourceWithUpdateLink }));
         service.pollCommand = jest.fn();
-        (<any>service.pollCommand).mockReturnValue(
-          cold('a', { a: createStateResource(commandResourceWithUpdateLink, true) }),
-        );
+        (<any>service.pollCommand).mockReturnValue(cold('a', { a: createStateResource(commandResourceWithUpdateLink, true) }));
       });
 
       it('should return value with loading true', () => {
         const result = service.revokeCommand(commandResource);
 
-        expect(result).toBeObservable(
-          hot('a', { a: createStateResource(commandResourceWithUpdateLink, true) }),
-        );
+        expect(result).toBeObservable(hot('a', { a: createStateResource(commandResourceWithUpdateLink, true) }));
       });
     });
 
@@ -189,6 +170,7 @@ describe('CommandService', () => {
     it.skip('should call handleCommandError', () => {
       service.handleCommandError = jest.fn();
       const commandWithError: CommandResource = createCommandErrorResource();
+
       service.handleCommand(commandWithError);
 
       expect(service.handleCommandError).toHaveBeenCalledWith(commandWithError);
@@ -270,9 +252,7 @@ describe('CommandService', () => {
     it('should return stateResource still loading', () => {
       const result = service.getAndUpdate(commandResource);
 
-      expect(result).toBeObservable(
-        hot('a', { a: createStateResource(commandResourceWithUpdateLink, true) }),
-      );
+      expect(result).toBeObservable(hot('a', { a: createStateResource(commandResourceWithUpdateLink, true) }));
     });
 
     describe('command is loaded', () => {
@@ -327,20 +307,17 @@ describe('CommandService', () => {
     });
   });
 
-  describe('get pending commands', () => {
+  describe('get commands', () => {
     const commandListResource: CommandListResource = createCommandListResource();
 
     beforeEach(() => {
-      repository.getPendingCommands.mockReturnValue(cold('a', { a: commandListResource }));
+      repository.getCommands.mockReturnValue(cold('a', { a: commandListResource }));
     });
 
     it('should call repository', () => {
-      service.getPendingCommands(commandResource, CommandLinkRel.SELF);
+      service.getCommands(commandResource, CommandLinkRel.SELF);
 
-      expect(repository.getPendingCommands).toHaveBeenLastCalledWith(
-        commandResource,
-        CommandLinkRel.SELF,
-      );
+      expect(repository.getCommands).toHaveBeenLastCalledWith(commandResource, CommandLinkRel.SELF);
     });
   });
 
@@ -380,10 +357,12 @@ describe('CommandService', () => {
   });
 
   describe('createCommandByProps', () => {
-    const createCommandProps: CreateCommandProps = { ...createCreateCommandProps(), command };
+    const linkRel: LinkRelationName = faker.string.alpha(6);
+    const resource: Resource = createDummyResource([linkRel]);
+    const createCommandProps: CreateCommandProps = { ...createCreateCommandProps(), command, resource, linkRel };
 
     beforeEach(() => {
-      service.getCommandByOrder = jest.fn().mockReturnValue(of(commandStateResource));
+      service._getCommand = jest.fn().mockReturnValue(of(commandStateResource));
     });
 
     it('should dispatch action', () => {
@@ -394,7 +373,7 @@ describe('CommandService', () => {
 
     it('should call get command by order', (done) => {
       service.createCommandByProps(createCommandProps).subscribe(() => {
-        expect(service.getCommandByOrder).toHaveBeenCalledWith(command.order);
+        expect(service._getCommand).toHaveBeenCalledWith(command.order, getUrl(resource, linkRel));
         done();
       });
 
@@ -411,12 +390,14 @@ describe('CommandService', () => {
     });
   });
 
-  describe('get command by order', () => {
+  describe('get command', () => {
+    const uri: ResourceUri = faker.internet.url();
+
     it('should select from store', (done) => {
-      const selectorSpy = jest.spyOn(Selectors, 'commandByOrder');
+      const selectorSpy = jest.spyOn(Selectors, 'command');
 
-      service.getCommandByOrder(CommandOrder.VORGANG_ANNEHMEN).subscribe(() => {
-        expect(selectorSpy).toHaveBeenCalledWith(CommandOrder.VORGANG_ANNEHMEN);
+      service._getCommand(CommandOrder.VORGANG_ANNEHMEN, uri).subscribe(() => {
+        expect(selectorSpy).toHaveBeenCalledWith(CommandOrder.VORGANG_ANNEHMEN, uri);
         done();
       });
 
@@ -424,7 +405,7 @@ describe('CommandService', () => {
     });
 
     it('should return value', (done) => {
-      service.getCommandByOrder(CommandOrder.VORGANG_ANNEHMEN).subscribe((selected) => {
+      service._getCommand(CommandOrder.VORGANG_ANNEHMEN, uri).subscribe((selected) => {
         expect(selected).toBe(commandStateResource);
         done();
       });
@@ -436,7 +417,7 @@ describe('CommandService', () => {
       store.select.mockReturnValue(of(null));
 
       let success: boolean = true;
-      service.getCommandByOrder(<CommandOrder>'anyOrder').subscribe({
+      service._getCommand(<CommandOrder>'anyOrder', uri).subscribe({
         next: (commandStateResource: StateResource<CommandResource>) => {
           success = commandStateResource !== null;
         },
diff --git a/alfa-client/libs/command-shared/src/lib/command.service.ts b/alfa-client/libs/command-shared/src/lib/command.service.ts
index 8c4a5ec1a7..8e035ec94f 100644
--- a/alfa-client/libs/command-shared/src/lib/command.service.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.service.ts
@@ -32,18 +32,12 @@ import { SnackBarService } from '@alfa-client/ui';
 import { HttpErrorResponse } from '@angular/common/http';
 import { Injectable } from '@angular/core';
 import { Store } from '@ngrx/store';
-import { Resource } from '@ngxp/rest';
+import { getUrl, Resource, ResourceUri } from '@ngxp/rest';
 import { Observable, of, Subject, throwError } from 'rxjs';
 import { catchError, filter, map, mergeMap, tap } from 'rxjs/operators';
 import { CommandEffects } from './+state/command.effects';
 import { COMMAND_ERROR_MESSAGES } from './command.message';
-import {
-  CommandListResource,
-  CommandOrder,
-  CommandResource,
-  CreateCommand,
-  CreateCommandProps,
-} from './command.model';
+import { CommandListResource, CommandOrder, CommandResource, CreateCommand, CreateCommandProps } from './command.model';
 import { CommandRepository } from './command.repository';
 import { isConcurrentModification, isPending } from './command.util';
 
@@ -63,11 +57,7 @@ export class CommandService {
   /**
    * @deprecated Use createCommandByProps(createCommandProps: CreateCommandProps) instead.
    */
-  public createCommand(
-    resource: Resource,
-    linkRel: string,
-    command: CreateCommand,
-  ): Observable<StateResource<CommandResource>> {
+  public createCommand(resource: Resource, linkRel: string, command: CreateCommand): Observable<StateResource<CommandResource>> {
     return this.handleCommandResponse(this.repository.createCommand(resource, linkRel, command));
   }
 
@@ -75,9 +65,7 @@ export class CommandService {
     return this.handleCommandResponse(this.repository.revokeCommand(resource));
   }
 
-  private handleCommandResponse(
-    command$: Observable<CommandResource>,
-  ): Observable<StateResource<CommandResource>> {
+  private handleCommandResponse(command$: Observable<CommandResource>): Observable<StateResource<CommandResource>> {
     return command$.pipe(
       mergeMap((command) => this.handleCommand(command)),
       catchError((errorResponse) => this.handleHttpError(errorResponse)),
@@ -99,6 +87,7 @@ export class CommandService {
     return this.startPolling(command);
   }
 
+  // TODO: Pruefen, ob die Funktion noch gebraucht wird
   handleCommandError(command: CommandResource): Observable<StateResource<CommandResource>> {
     if (isConcurrentModification(command.errorMessage)) {
       this.snackBarService.showError(COMMAND_ERROR_MESSAGES[command.errorMessage]);
@@ -106,11 +95,10 @@ export class CommandService {
     }
     return of(createStateResource(command));
   }
+  //
 
   startPolling(commandResource: CommandResource): Observable<StateResource<CommandResource>> {
-    return isPending(commandResource) ?
-        this.pollCommand(commandResource)
-      : of(createStateResource(commandResource));
+    return isPending(commandResource) ? this.pollCommand(commandResource) : of(createStateResource(commandResource));
   }
 
   public pollCommand(commandResource: CommandResource): Observable<StateResource<CommandResource>> {
@@ -121,10 +109,7 @@ export class CommandService {
     );
   }
 
-  handleInterval(
-    stateResource: StateResource<CommandResource>,
-    interval: IntervallHandleWithTickObservable,
-  ): void {
+  handleInterval(stateResource: StateResource<CommandResource>, interval: IntervallHandleWithTickObservable): void {
     if (!stateResource.loading) this.clearInterval(interval.handle);
   }
 
@@ -142,23 +127,24 @@ export class CommandService {
     window.clearInterval(handler);
   }
 
-  public getPendingCommands(resource: Resource, linkRel: string): Observable<CommandListResource> {
-    return this.repository.getPendingCommands(resource, linkRel);
+  //TODO Pruefen, ob die Funktion noch gebraucht wird
+  public getCommands(resource: Resource, linkRel: string): Observable<CommandListResource> {
+    return this.repository.getCommands(resource, linkRel);
   }
-
+  //
+  //TODO Pruefen, ob die Funktion noch gebraucht wird
   public getEffectedResource<T>(command: CommandResource): Observable<T> {
     return this.repository.getEffectedResource(command);
   }
+  //
 
-  public createCommandByProps(
-    createCommandProps: CreateCommandProps,
-  ): Observable<StateResource<CommandResource>> {
+  public createCommandByProps(createCommandProps: CreateCommandProps): Observable<StateResource<CommandResource>> {
     this.store.dispatch(Actions.createCommand(createCommandProps));
-    return this.getCommandByOrder(createCommandProps.command.order);
+    return this._getCommand(createCommandProps.command.order, getUrl(createCommandProps.resource, createCommandProps.linkRel));
   }
 
-  public getCommandByOrder(order: CommandOrder): Observable<StateResource<CommandResource>> {
-    return this.store.select(Selectors.commandByOrder(order)).pipe(filter(isNotNil));
+  _getCommand(order: CommandOrder, uri: ResourceUri): Observable<StateResource<CommandResource>> {
+    return this.store.select(Selectors.command(order, uri)).pipe(filter(isNotNil));
   }
 }
 
diff --git a/alfa-client/libs/command-shared/src/lib/command.util.spec.ts b/alfa-client/libs/command-shared/src/lib/command.util.spec.ts
index d8dc15892b..f3cd21cee6 100644
--- a/alfa-client/libs/command-shared/src/lib/command.util.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.util.spec.ts
@@ -21,11 +21,23 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { createCommandErrorResource, createCommandListResource, createCommandResource, } from 'libs/command-shared/test/command';
+import { createStateResource } from '@alfa-client/tech-shared';
+import { getUrl } from '@ngxp/rest';
+import { createCommandErrorResource, createCommandListResource, createCommandResource } from 'libs/command-shared/test/command';
 import { CommandLinkRel } from './command.linkrel';
 import { CommandErrorMessage } from './command.message';
-import { CommandListResource, CommandResource } from './command.model';
-import { getPendingCommandByOrder, hasCommandError, isConcurrentModification, isDone, isPending, isRevokeable, isSuccessfulDone, notHasCommandError, } from './command.util';
+import { CommandListResource, CommandResource, CommandStatus } from './command.model';
+import {
+  buildPendingCommandMap,
+  getPendingCommandByOrder,
+  hasCommandError,
+  isConcurrentModification,
+  isDone,
+  isPending,
+  isRevokeable,
+  isSuccessfulDone,
+  notHasCommandError,
+} from './command.util';
 
 describe('CommandUtil', () => {
   describe('isRevokeable', () => {
@@ -112,20 +124,34 @@ describe('CommandUtil', () => {
       const command: CommandResource = { ...createCommandResource(), order: anotherOrder };
       const listResource: CommandListResource = createCommandListResource([command]);
 
-      const pendingCommand: CommandResource = getPendingCommandByOrder(listResource, [
-        order,
-        anotherOrder,
-      ]);
+      const pendingCommand: CommandResource = getPendingCommandByOrder(listResource, [order, anotherOrder]);
 
       expect(pendingCommand).toBe(command);
     });
   });
 
+  describe('build pending command map', () => {
+    it('should return map', () => {
+      const pendingCommand1: CommandResource = {
+        ...createCommandResource([CommandLinkRel.RELATED_RESOURCE]),
+        status: CommandStatus.PENDING,
+      };
+      const pendingCommand2: CommandResource = {
+        ...createCommandResource([CommandLinkRel.RELATED_RESOURCE]),
+        status: CommandStatus.PENDING,
+      };
+      const commandList: CommandListResource = createCommandListResource([pendingCommand1, pendingCommand2]);
+
+      const map = buildPendingCommandMap(commandList);
+
+      expect(map[getUrl(pendingCommand1, CommandLinkRel.RELATED_RESOURCE)]).toEqual(createStateResource(pendingCommand1));
+      expect(map[getUrl(pendingCommand2, CommandLinkRel.RELATED_RESOURCE)]).toEqual(createStateResource(pendingCommand2));
+    });
+  });
+
   describe('isConcurrentModification', () => {
     it('should return true on matching error message', () => {
-      const doesMatch: boolean = isConcurrentModification(
-        CommandErrorMessage.CONCURRENT_MODIFICATION,
-      );
+      const doesMatch: boolean = isConcurrentModification(CommandErrorMessage.CONCURRENT_MODIFICATION);
 
       expect(doesMatch).toBeTruthy();
     });
diff --git a/alfa-client/libs/command-shared/src/lib/command.util.ts b/alfa-client/libs/command-shared/src/lib/command.util.ts
index 70e446bee6..820a223daa 100644
--- a/alfa-client/libs/command-shared/src/lib/command.util.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.util.ts
@@ -21,6 +21,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { createStateResource } from '@alfa-client/tech-shared';
 import { getEmbeddedResource, getUrl, hasLink, ResourceUri } from '@ngxp/rest';
 import { isEmpty, isNil, isObject } from 'lodash-es';
 import { CommandLinkRel, CommandListLinkRel } from './command.linkrel';
@@ -51,21 +52,26 @@ export function notHasCommandError(commandResource: CommandResource): boolean {
   return !hasCommandError(commandResource);
 }
 
-export function getPendingCommandByOrder(
-  pendingCommands: CommandListResource,
-  commandOrder: any[],
-): CommandResource {
-  const commands: CommandResource[] = getEmbeddedCommandResources(pendingCommands).filter(
-    (command) => commandOrder.includes(command.order),
+export function getPendingCommandByOrder(pendingCommands: CommandListResource, commandOrder: any[]): CommandResource {
+  const commands: CommandResource[] = getEmbeddedCommandResources(pendingCommands).filter((command: CommandResource) =>
+    commandOrder.includes(command.order),
   );
   return commands.length > 0 ? commands[0] : null;
 }
 
+export function buildPendingCommandMap(commandList: CommandListResource): any {
+  let map = {};
+  const commands: CommandResource[] = getEmbeddedCommandResources(commandList);
+  commands.forEach((command: CommandResource) => {
+    if (hasLink(command, CommandLinkRel.RELATED_RESOURCE)) {
+      map[getUrl(command, CommandLinkRel.RELATED_RESOURCE)] = createStateResource(command);
+    }
+  });
+  return map;
+}
+
 function getEmbeddedCommandResources(commandListResource: CommandListResource): CommandResource[] {
-  return getEmbeddedResource<CommandResource[]>(
-    commandListResource,
-    CommandListLinkRel.COMMAND_LIST,
-  );
+  return getEmbeddedResource<CommandResource[]>(commandListResource, CommandListLinkRel.COMMAND_LIST);
 }
 
 export function doIfCommandIsDone(commandResource: CommandResource, action: () => void) {
diff --git a/alfa-client/libs/command-shared/test/command.ts b/alfa-client/libs/command-shared/test/command.ts
index 05fec9de48..976d353de2 100644
--- a/alfa-client/libs/command-shared/test/command.ts
+++ b/alfa-client/libs/command-shared/test/command.ts
@@ -36,6 +36,7 @@ import {
   CreateCommand,
   CreateCommandProps,
   CreateCommandPropsWithoutResource,
+  PendingCommandMap,
 } from '../src/lib/command.model';
 
 export function createCommand(): Command {
@@ -104,3 +105,7 @@ export function createSuccessfullyDoneCommandStateResource(): StateResource<Comm
 export function createSuccessfullyDoneCommandResource(): CommandResource {
   return createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]);
 }
+
+export function createPendingCommandMap(): PendingCommandMap {
+  return { [faker.internet.url()]: createCommandStateResource() };
+}
diff --git a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
index 492502ba27..5c12de2fd8 100644
--- a/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
+++ b/alfa-client/libs/postfach-shared/src/lib/postfach.service.spec.ts
@@ -31,10 +31,12 @@ import { VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang
 import { TestBed } from '@angular/core/testing';
 import { MatDialog } from '@angular/material/dialog';
 import { expect } from '@jest/globals';
+import { getUrl } from '@ngxp/rest';
 import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel';
 import { createCommandErrorResource, createCommandResource } from 'libs/command-shared/test/command';
 import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
-import { BehaviorSubject, of } from 'rxjs';
+import { BehaviorSubject, Observable, of } from 'rxjs';
+import { singleColdCompleted } from '../../../tech-shared/test/marbles';
 import {
   createPostfachFeatures,
   createPostfachMail,
@@ -632,4 +634,35 @@ describe('PostfachService', () => {
       });
     });
   });
+
+  describe('get pending resend command', () => {
+    const postfachNachricht: PostfachMailResource = createPostfachMailResource();
+
+    const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]);
+    const commandStateResource: StateResource<CommandResource> = createStateResource(command);
+
+    beforeEach(() => {
+      vorgangService.getAndPollPendingCommand.mockReturnValue(of(commandStateResource));
+      service._refreshPostfachMailList = jest.fn();
+    });
+
+    it('should call vorgang service', () => {
+      service.getPendingResendCommand(postfachNachricht);
+
+      expect(vorgangService.getAndPollPendingCommand).toHaveBeenCalledWith(getUrl(postfachNachricht));
+    });
+
+    it('should call refresh list on command successfully done', () => {
+      service.getPendingResendCommand(postfachNachricht).subscribe();
+
+      expect(service._refreshPostfachMailList).toHaveBeenCalled();
+    });
+
+    it('should return value', () => {
+      const pendingResendCommand$: Observable<StateResource<CommandResource>> =
+        service.getPendingResendCommand(postfachNachricht);
+
+      expect(pendingResendCommand$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
+  });
 });
diff --git a/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts b/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts
index b7fbfbe62d..a5dbb53f46 100644
--- a/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts
+++ b/alfa-client/libs/postfach-shared/src/lib/postfach.service.ts
@@ -30,6 +30,7 @@ import {
   hasCommandError,
   isDone,
   isPending,
+  tapOnCommandSuccessfullyDone,
 } from '@alfa-client/command-shared';
 import { NavigationService } from '@alfa-client/navigation-shared';
 import {
@@ -46,7 +47,7 @@ import { VorgangResource, VorgangService, VorgangWithEingangResource } from '@al
 import { inject, Injectable } from '@angular/core';
 import { MatDialog } from '@angular/material/dialog';
 import { Params } from '@angular/router';
-import { hasLink, Resource } from '@ngxp/rest';
+import { getUrl, hasLink, Resource } from '@ngxp/rest';
 import { isNil, isNull } from 'lodash-es';
 import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs';
 import { first, map, take, tap } from 'rxjs/operators';
@@ -75,11 +76,12 @@ export class PostfachService {
   private readonly postfachFacade = inject(PostfachFacade);
   private readonly binaryFileService = inject(BinaryFileService);
 
-  private readonly isPollSendPostachMail: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
   postfachMailList$: BehaviorSubject<StateResource<PostfachMailListResource>> = new BehaviorSubject<
     StateResource<PostfachMailListResource>
   >(createEmptyStateResource<PostfachMailListResource>());
 
+  private readonly isPollSendPostachMail: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
+
   private navigationSubscription: Subscription;
 
   private sendPostfachMailSubscription: Subscription;
@@ -160,6 +162,14 @@ export class PostfachService {
       .pipe(map((pendingCommand) => this._pollSendPostfachMailCommand(pendingCommand)));
   }
 
+  public getPendingResendCommand(postfachNachricht: PostfachMailResource): Observable<StateResource<CommandResource>> {
+    return this.vorgangService.getAndPollPendingCommand(getUrl(postfachNachricht)).pipe(
+      tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) => {
+        this._refreshPostfachMailList(commandStateResource);
+      }),
+    );
+  }
+
   _listenToNavigation(): void {
     this._unsubscribeToNavigation();
     this.navigationSubscription = this.navigationService.urlChanged().subscribe((params) => this._onNavigation(params));
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts
index 20855cb121..c531c4853a 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.spec.ts
@@ -22,11 +22,11 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import { CommandResource } from '@alfa-client/command-shared';
-import { PostfachMailLinkRel, PostfachService } from '@alfa-client/postfach-shared';
+import { PostfachMailLinkRel, PostfachMailResource, PostfachService } from '@alfa-client/postfach-shared';
 import { createEmptyStateResource, createStateResource, HasLinkPipe, StateResource } from '@alfa-client/tech-shared';
 import { existsAsHtmlElement, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { createCommandResource } from 'libs/command-shared/test/command';
+import { createCommandResource, createCommandStateResource } from 'libs/command-shared/test/command';
 import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
 import { MockComponent } from 'ng-mocks';
 import { of } from 'rxjs';
@@ -39,19 +39,23 @@ describe('OutgoingMailErrorContainerComponent', () => {
   let component: OutgoingMailErrorContainerComponent;
   let fixture: ComponentFixture<OutgoingMailErrorContainerComponent>;
 
-  let postfachService: Mock<PostfachService>;
+  let service: Mock<PostfachService>;
 
   const mailError: string = getDataTestIdOf('outgoing-mail-error');
 
+  const postfachNachricht: PostfachMailResource = createPostfachMailResource();
+
+  const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
+
   beforeEach(async () => {
-    postfachService = mock(PostfachService);
+    service = mock(PostfachService);
 
     await TestBed.configureTestingModule({
       declarations: [OutgoingMailErrorContainerComponent, MockComponent(OutgoingMailErrorComponent), HasLinkPipe],
       providers: [
         {
           provide: PostfachService,
-          useValue: postfachService,
+          useValue: service,
         },
       ],
     }).compileComponents();
@@ -60,6 +64,7 @@ describe('OutgoingMailErrorContainerComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(OutgoingMailErrorContainerComponent);
     component = fixture.componentInstance;
+    component.postfachMailResource = postfachNachricht;
     fixture.detectChanges();
   });
 
@@ -67,17 +72,35 @@ describe('OutgoingMailErrorContainerComponent', () => {
     expect(component).toBeTruthy();
   });
 
+  describe('on init', () => {
+    beforeEach(() => {
+      service.getPendingResendCommand.mockReturnValue(of(commandStateResource));
+    });
+
+    it('should call postfach service to get pending resend command', () => {
+      component.ngOnInit();
+
+      expect(service.getPendingResendCommand).toHaveBeenCalledWith(postfachNachricht);
+    });
+
+    it('should assign response', () => {
+      component.ngOnInit();
+
+      expect(component.resendPostfachMailStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
+  });
+
   describe('resendMail', () => {
     const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource());
 
     beforeEach(() => {
-      postfachService.resendMail.mockReturnValue(of(commandStateResource));
+      service.resendMail.mockReturnValue(of(commandStateResource));
     });
 
     it('should call postfach service', () => {
       component.resendMail();
 
-      expect(postfachService.resendMail).toHaveBeenCalled();
+      expect(service.resendMail).toHaveBeenCalled();
     });
 
     it('should assign service response', () => {
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts
index c0d8d6589d..221f5d478b 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-list-container/postfach-mail-list/postfach-mail/outgoing-mail/outgoing-mail-error-container/outgoing-mail-error-container.component.ts
@@ -41,8 +41,8 @@ export class OutgoingMailErrorContainerComponent implements OnInit {
 
   public readonly PostfachMailLinkRel = PostfachMailLinkRel;
 
-  ngOnInit() {
-    this.resendPostfachMailStateResource$ = this.postfachService.getPendingSendPostfachMailCommand();
+  ngOnInit(): void {
+    this.resendPostfachMailStateResource$ = this.postfachService.getPendingResendCommand(this.postfachMailResource);
   }
 
   public resendMail(): void {
diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.actions.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.actions.ts
index 45eb6a8ae7..e22edf8965 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.actions.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.actions.ts
@@ -21,25 +21,13 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { HttpErrorResponse } from '@angular/common/http';
 import { ApiRootResource } from '@alfa-client/api-root-shared';
 import { LoadBinaryFileListSuccessProps } from '@alfa-client/binary-file-shared';
-import {
-  CommandStateResourceProps,
-  LoadCommandListSuccessProps,
-} from '@alfa-client/command-shared';
-import {
-  ApiErrorAction,
-  ResourceUriProps,
-  TypedActionCreator,
-  TypedActionCreatorWithProps,
-} from '@alfa-client/tech-shared';
+import { CommandStateResourceProps, LoadCommandListSuccessProps, UpdateCommandProps } from '@alfa-client/command-shared';
+import { ApiErrorAction, ResourceUriProps, TypedActionCreator, TypedActionCreatorWithProps } from '@alfa-client/tech-shared';
+import { HttpErrorResponse } from '@angular/common/http';
 import { createAction, props } from '@ngrx/store';
-import {
-  AdditionalActions,
-  VorgangListResource,
-  VorgangWithEingangResource,
-} from '../vorgang.model';
+import { AdditionalActions, VorgangListResource, VorgangWithEingangResource } from '../vorgang.model';
 
 export interface SearchVorgaengeByProps {
   apiRoot: ApiRootResource;
@@ -96,16 +84,16 @@ export const searchVorgaengeBy: TypedActionCreatorWithProps<SearchVorgaengeByPro
   '[Vorgang] Search VorgangList',
   props<SearchVorgaengeByProps>(),
 );
-export const searchVorgaengeBySuccess: TypedActionCreatorWithProps<VorgangListAction> =
-  createAction('[Vorgang] Search VorgangList Success', props<VorgangListAction>());
+export const searchVorgaengeBySuccess: TypedActionCreatorWithProps<VorgangListAction> = createAction(
+  '[Vorgang] Search VorgangList Success',
+  props<VorgangListAction>(),
+);
 export const searchVorgaengeByFailure: TypedActionCreatorWithProps<HttpErrorAction> = createAction(
   '[Vorgang] Search VorgangList Failure',
   props<HttpErrorAction>(),
 );
 
-export const loadNextPage: TypedActionCreator = createAction(
-  '[Vorgang] Load next VorgangList page',
-);
+export const loadNextPage: TypedActionCreator = createAction('[Vorgang] Load next VorgangList page');
 export const loadNextPageSuccess: TypedActionCreatorWithProps<VorgangListAction> = createAction(
   '[Vorgang] Load next VorgangList page Success',
   props<VorgangListAction>(),
@@ -125,9 +113,7 @@ export const searchForPreviewFailure: TypedActionCreatorWithProps<HttpErrorActio
   props<HttpErrorAction>(),
 );
 
-export const clearSearchPreviewList: TypedActionCreator = createAction(
-  '[Vorgang] Clear search preview list',
-);
+export const clearSearchPreviewList: TypedActionCreator = createAction('[Vorgang] Clear search preview list');
 export const clearSearchString: TypedActionCreator = createAction('[Vorgang] Clear search string');
 
 export const setSearchString: TypedActionCreatorWithProps<StringBasedProps> = createAction(
@@ -136,56 +122,70 @@ export const setSearchString: TypedActionCreatorWithProps<StringBasedProps> = cr
 );
 
 //VorgangWithEingang
-export const loadVorgangWithEingang: TypedActionCreatorWithProps<VorgangUriWithContextProps> =
-  createAction('[Vorgang] Load VorgangWithEingang', props<VorgangUriWithContextProps>());
-export const loadVorgangWithEingangSuccess: TypedActionCreatorWithProps<VorgangWithEingangAction> =
-  createAction('[Vorgang] Load VorgangWithEingang Success', props<VorgangWithEingangAction>());
-export const loadVorgangWithEingangFailure: TypedActionCreatorWithProps<ApiErrorAction> =
-  createAction('[Vorgang] Load VorgangWithEingang Failure', props<ApiErrorAction>());
-
-export const clearVorgangWithEingang: TypedActionCreator = createAction(
-  '[Vorgang] Clear VorgangWithEingang',
-);
-export const setReloadVorgangWithEingang: TypedActionCreator = createAction(
-  '[Vorgang] Set reload at VorgangWithEingang',
-);
-
-export const loadPendingCommandList: TypedActionCreatorWithProps<VorgangWithEingangAction> =
-  createAction('[Vorgang] Load pending command list', props<VorgangWithEingangAction>());
-export const loadPendingCommandListSuccess: TypedActionCreatorWithProps<LoadCommandListSuccessProps> =
-  createAction(
-    '[Vorgang/API] Load pending command list Success',
-    props<LoadCommandListSuccessProps>(),
-  );
-export const loadPendingCommandListFailure: TypedActionCreatorWithProps<ApiErrorAction> =
-  createAction('[Vorgang/API] Load pending command list Failure', props<ApiErrorAction>());
-
-export const loadAttachmentList: TypedActionCreatorWithProps<VorgangWithEingangAction> =
-  createAction('[Vorgang] Load AttachmentList', props<VorgangWithEingangAction>());
-export const loadAttachmentListSuccess: TypedActionCreatorWithProps<LoadBinaryFileListSuccessProps> =
-  createAction('[Vorgang] Load AttachmentList Success', props<LoadBinaryFileListSuccessProps>());
+export const loadVorgangWithEingang: TypedActionCreatorWithProps<VorgangUriWithContextProps> = createAction(
+  '[Vorgang] Load VorgangWithEingang',
+  props<VorgangUriWithContextProps>(),
+);
+export const loadVorgangWithEingangSuccess: TypedActionCreatorWithProps<VorgangWithEingangAction> = createAction(
+  '[Vorgang] Load VorgangWithEingang Success',
+  props<VorgangWithEingangAction>(),
+);
+export const loadVorgangWithEingangFailure: TypedActionCreatorWithProps<ApiErrorAction> = createAction(
+  '[Vorgang] Load VorgangWithEingang Failure',
+  props<ApiErrorAction>(),
+);
+
+export const clearVorgangWithEingang: TypedActionCreator = createAction('[Vorgang] Clear VorgangWithEingang');
+export const setReloadVorgangWithEingang: TypedActionCreator = createAction('[Vorgang] Set reload at VorgangWithEingang');
+
+export const loadPendingCommandList: TypedActionCreatorWithProps<VorgangWithEingangAction> = createAction(
+  '[Vorgang] Load pending command list',
+  props<VorgangWithEingangAction>(),
+);
+export const loadPendingCommandListSuccess: TypedActionCreatorWithProps<LoadCommandListSuccessProps> = createAction(
+  '[Vorgang/API] Load pending command list Success',
+  props<LoadCommandListSuccessProps>(),
+);
+export const loadPendingCommandListFailure: TypedActionCreatorWithProps<ApiErrorAction> = createAction(
+  '[Vorgang/API] Load pending command list Failure',
+  props<ApiErrorAction>(),
+);
+
+export const loadAttachmentList: TypedActionCreatorWithProps<VorgangWithEingangAction> = createAction(
+  '[Vorgang] Load AttachmentList',
+  props<VorgangWithEingangAction>(),
+);
+export const loadAttachmentListSuccess: TypedActionCreatorWithProps<LoadBinaryFileListSuccessProps> = createAction(
+  '[Vorgang] Load AttachmentList Success',
+  props<LoadBinaryFileListSuccessProps>(),
+);
 export const loadAttachmentListFailure: TypedActionCreatorWithProps<ApiErrorAction> = createAction(
   '[Vorgang] Load AttachmentList Failure',
   props<ApiErrorAction>(),
 );
 
-export const loadRepresentationList: TypedActionCreatorWithProps<VorgangWithEingangAction> =
-  createAction('[Vorgang] Load RepresentationList', props<VorgangWithEingangAction>());
-export const loadRepresentationListSuccess: TypedActionCreatorWithProps<LoadBinaryFileListSuccessProps> =
-  createAction(
-    '[Vorgang] Load RepresentationList Success',
-    props<LoadBinaryFileListSuccessProps>(),
-  );
-export const loadRepresentationListFailure: TypedActionCreatorWithProps<ApiErrorAction> =
-  createAction('[Vorgang] Load RepresentationList Failure', props<ApiErrorAction>());
+export const loadRepresentationList: TypedActionCreatorWithProps<VorgangWithEingangAction> = createAction(
+  '[Vorgang] Load RepresentationList',
+  props<VorgangWithEingangAction>(),
+);
+export const loadRepresentationListSuccess: TypedActionCreatorWithProps<LoadBinaryFileListSuccessProps> = createAction(
+  '[Vorgang] Load RepresentationList Success',
+  props<LoadBinaryFileListSuccessProps>(),
+);
+export const loadRepresentationListFailure: TypedActionCreatorWithProps<ApiErrorAction> = createAction(
+  '[Vorgang] Load RepresentationList Failure',
+  props<ApiErrorAction>(),
+);
 
-export const setForwardingSingleCommand: TypedActionCreatorWithProps<CommandStateResourceProps> =
-  createAction('[Vorgang] Set forward command', props<CommandStateResourceProps>());
-export const setForwardingSingleCommandLoading: TypedActionCreator = createAction(
-  '[Vorgang] Set forward command loading',
+export const setForwardingSingleCommand: TypedActionCreatorWithProps<CommandStateResourceProps> = createAction(
+  '[Vorgang] Set forward command',
+  props<CommandStateResourceProps>(),
+);
+export const setForwardingSingleCommandLoading: TypedActionCreator = createAction('[Vorgang] Set forward command loading');
+export const setSendPostfachNachrichtSingleCommand: TypedActionCreatorWithProps<CommandStateResourceProps> = createAction(
+  '[Vorgang] Set send postfach nachricht command',
+  props<CommandStateResourceProps>(),
 );
-export const setSendPostfachNachrichtSingleCommand: TypedActionCreatorWithProps<CommandStateResourceProps> =
-  createAction('[Vorgang] Set send postfach nachricht command', props<CommandStateResourceProps>());
 export const setSendPostfachNachrichtSingleCommandLoading: TypedActionCreator = createAction(
   '[Vorgang] Set send postfach nachricht command loading',
 );
@@ -201,3 +201,13 @@ export const exportVorgangFailure: TypedActionCreatorWithProps<ApiErrorAction> =
   '[Vorgang] Export Failure',
   props<ApiErrorAction>(),
 );
+
+export const setPendingCommandLoading: TypedActionCreatorWithProps<ResourceUriProps> = createAction(
+  '[Vorgang] Set pending command loading',
+  props<ResourceUriProps>(),
+);
+
+export const updatePendingCommand: TypedActionCreatorWithProps<UpdateCommandProps> = createAction(
+  '[Vorgang] Update pending command',
+  props<UpdateCommandProps>(),
+);
diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts
index c2e342d93c..70e6360f76 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts
@@ -23,7 +23,14 @@
  */
 import { ApiRootResource } from '@alfa-client/api-root-shared';
 import { BinaryFileListResource } from '@alfa-client/binary-file-shared';
-import { CommandListResource, CommandOrder, CommandResource, CreateCommand } from '@alfa-client/command-shared';
+import {
+  CommandListResource,
+  CommandOrder,
+  CommandResource,
+  CreateCommand,
+  CreateCommandProps,
+  PendingCommandMap,
+} from '@alfa-client/command-shared';
 import { RouteData } from '@alfa-client/navigation-shared';
 import {
   ApiError,
@@ -35,11 +42,19 @@ import {
 } from '@alfa-client/tech-shared';
 import { HttpErrorResponse } from '@angular/common/http';
 import { UrlSegment } from '@angular/router';
+import { faker } from '@faker-js/faker';
 import { Action } from '@ngrx/store';
 import { Resource, ResourceUri } from '@ngxp/rest';
 import { createApiRootResource } from 'libs/api-root-shared/test/api-root';
 import { createBinaryFileListResource } from 'libs/binary-file-shared/test/binary-file';
-import { createCommand, createCommandListResource, createCommandResource } from 'libs/command-shared/test/command';
+import {
+  createCommand,
+  createCommandListResource,
+  createCommandResource,
+  createCommandStateResource,
+  createCreateCommandProps,
+  createPendingCommandMap,
+} from 'libs/command-shared/test/command';
 import { createRouteData } from 'libs/navigation-shared/test/navigation-test-factory';
 import { createDummyResource } from 'libs/tech-shared/test/resource';
 import {
@@ -70,11 +85,10 @@ import {
 import { VorgangListAction } from './vorgang.actions';
 import { VorgangState, initialState, reducer } from './vorgang.reducer';
 
-import { faker } from '@faker-js/faker';
-
 import * as Storage from '@alfa-client/app-shared';
 import * as CommandActions from '@alfa-client/command-shared';
 import * as NavigationActions from '@alfa-client/navigation-shared';
+import * as CommandUtil from '../../../../command-shared/src/lib/command.util';
 import * as VorgangActions from './vorgang.actions';
 import * as Reducer from './vorgang.reducer';
 
@@ -508,6 +522,52 @@ describe('Vorgang Reducer', () => {
 
         expect(state.sendPostfachNachrichtPendingCommand.resource).toBe(sendPostfachNachrichtCommand);
       });
+
+      it('should call build pending command map', () => {
+        const buildPendingCommandMapSpy: jest.SpyInstance = jest.spyOn(CommandUtil, 'buildPendingCommandMap');
+        const commandList: CommandListResource = createCommandListResource();
+        const action: Action<string> = VorgangActions.loadPendingCommandListSuccess({ commandList });
+
+        reducer(initialState, action);
+
+        expect(buildPendingCommandMapSpy).toHaveBeenCalledWith(commandList);
+      });
+
+      it('should set pending commands map', () => {
+        const pendingCommandMap: PendingCommandMap = createPendingCommandMap();
+        jest.spyOn(CommandUtil, 'buildPendingCommandMap').mockReturnValue(pendingCommandMap);
+        const action = VorgangActions.loadPendingCommandListSuccess({ commandList: createCommandListResource() });
+
+        const state: VorgangState = reducer(initialState, action);
+
+        expect(state.pendingCommandMap).toBe(pendingCommandMap);
+      });
+    });
+    describe('on "setPendingCommandLoading" action', () => {
+      it('should set map entry state resource loading by uri', () => {
+        const resourceUri: ResourceUri = faker.internet.url();
+        const action = VorgangActions.setPendingCommandLoading({ resourceUri });
+        const pendingCommandMap: PendingCommandMap = { [resourceUri]: createCommandStateResource() };
+        const initialStateWithPendingCommandMap: VorgangState = { ...initialState, pendingCommandMap };
+
+        const state: VorgangState = reducer(initialStateWithPendingCommandMap, action);
+
+        expect(state.pendingCommandMap[resourceUri].loading).toBeTruthy();
+      });
+    });
+
+    describe('on "updatePendingCommand" action', () => {
+      it('should upadte map entry state resource by uri', () => {
+        const relatedResourceUri: ResourceUri = faker.internet.url();
+        const command: CommandResource = createCommandResource();
+        const action = VorgangActions.updatePendingCommand({ relatedResourceUri, command });
+        const pendingCommandMap: PendingCommandMap = { [relatedResourceUri]: { ...createCommandStateResource(), loading: true } };
+        const initialStateWithPendingCommandMap: VorgangState = { ...initialState, pendingCommandMap };
+
+        const state: VorgangState = reducer(initialStateWithPendingCommandMap, action);
+
+        expect(state.pendingCommandMap[relatedResourceUri]).toEqual(createStateResource(command));
+      });
     });
   });
 
@@ -606,12 +666,13 @@ describe('Vorgang Reducer', () => {
   });
 
   describe('createCommandSuccess', () => {
+    const createCommandProps: CreateCommandProps = createCreateCommandProps();
     const command: CommandResource = createCommandResource();
 
     it('should call getStatusCommandMapByCreateCommandSuccess', () => {
       const spy = jest.spyOn(Reducer, 'getStatusCommandMapByCreateCommandSuccess');
 
-      const action = CommandActions.createCommandSuccess({ command });
+      const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
       reducer(initialState, action);
 
@@ -621,7 +682,7 @@ describe('Vorgang Reducer', () => {
     it('should call getAssignUserCommandByCreateCommandSuccess', () => {
       const spy = jest.spyOn(Reducer, 'getAssignUserCommandByCreateCommandSuccess');
 
-      const action = CommandActions.createCommandSuccess({ command });
+      const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
       reducer(initialState, action);
 
@@ -631,7 +692,7 @@ describe('Vorgang Reducer', () => {
     it('should call getVorgangWithEingangStateResourceByCreateCommandSucces', () => {
       const spy = jest.spyOn(Reducer, 'getVorgangWithEingangStateResourceByCreateCommandSucces');
 
-      const action = CommandActions.createCommandSuccess({ command });
+      const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
       reducer(initialState, action);
 
diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts
index 2601e8b704..f9d63437e9 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts
@@ -31,12 +31,16 @@ import {
   CreateCommand,
   CreateCommandProps,
   LoadCommandListSuccessProps,
+  PendingCommandMap,
+  UpdateCommandProps,
+  buildPendingCommandMap,
   getPendingCommandByOrder,
 } from '@alfa-client/command-shared';
 import { RouteData } from '@alfa-client/navigation-shared';
 import {
   ApiErrorAction,
   EMPTY_STRING,
+  ResourceUriProps,
   StateResource,
   createEmptyStateResource,
   createErrorStateResource,
@@ -92,6 +96,7 @@ export interface VorgangState {
   assignUserCommand: StateResource<CommandResource>;
   forwardPendingCommand: StateResource<CommandResource>;
   sendPostfachNachrichtPendingCommand: StateResource<CommandResource>;
+  pendingCommandMap: PendingCommandMap;
   statusCommandMap: StatusCommandMap;
   revokeCommand: StateResource<CommandResource>;
   vorgangExport: StateResource<boolean>;
@@ -112,6 +117,7 @@ export const initialState: VorgangState = {
   assignUserCommand: createEmptyStateResource(),
   forwardPendingCommand: createEmptyStateResource(),
   sendPostfachNachrichtPendingCommand: createEmptyStateResource(),
+  pendingCommandMap: <any>{},
   statusCommandMap: <any>{},
   revokeCommand: createEmptyStateResource(),
   vorgangExport: createEmptyStateResource(),
@@ -332,6 +338,27 @@ const vorgangReducer: ActionReducer<VorgangState, Action> = createReducer(
       sendPostfachNachrichtPendingCommand: createStateResource(
         getPendingCommandByOrder(props.commandList, [CommandOrder.SEND_POSTFACH_NACHRICHT]),
       ),
+      pendingCommandMap: buildPendingCommandMap(props.commandList),
+    }),
+  ),
+  on(
+    VorgangActions.setPendingCommandLoading,
+    (state: VorgangState, props: ResourceUriProps): VorgangState => ({
+      ...state,
+      pendingCommandMap: {
+        ...state.pendingCommandMap,
+        [props.resourceUri]: { ...state.pendingCommandMap[props.resourceUri], loading: true },
+      },
+    }),
+  ),
+  on(
+    VorgangActions.updatePendingCommand,
+    (state: VorgangState, props: UpdateCommandProps): VorgangState => ({
+      ...state,
+      pendingCommandMap: {
+        ...state.pendingCommandMap,
+        [props.relatedResourceUri]: createStateResource(props.command),
+      },
     }),
   ),
 
diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts
index bd7c1be995..e8f4098294 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts
@@ -24,8 +24,10 @@
 import { BinaryFileListResource } from '@alfa-client/binary-file-shared';
 import { CommandOrder, CommandResource } from '@alfa-client/command-shared';
 import { StateResource, createStateResource } from '@alfa-client/tech-shared';
+import { faker } from '@faker-js/faker/.';
+import { ResourceUri } from '@ngxp/rest';
 import { createBinaryFileListResource } from 'libs/binary-file-shared/test/binary-file';
-import { createCommandResource } from 'libs/command-shared/test/command';
+import { createCommandResource, createCommandStateResource } from 'libs/command-shared/test/command';
 import {
   createVorgangListResource,
   createVorgangResources,
@@ -33,6 +35,7 @@ import {
   createVorgangWithEingangResource,
 } from 'libs/vorgang-shared/test/vorgang';
 import {
+  PendingCommandMap,
   StatusCommandMap,
   VorgangFilter,
   VorgangListResource,
@@ -49,42 +52,33 @@ import * as VorgangSelectors from './vorgang.selectors';
 describe('Vorgang Selectors', () => {
   let state: VorgangPartialState;
 
-  const vorgangList: StateResource<VorgangListResource> = createStateResource(
-    createVorgangListResource(),
-  );
+  const vorgangList: StateResource<VorgangListResource> = createStateResource(createVorgangListResource());
   const vorgaenge: VorgangResource[] = createVorgangResources();
-  const vorgangStatistic: StateResource<VorgangStatistic> =
-    createStateResource(createVorgangStatistic());
-  const searchPreviewList: StateResource<VorgangListResource> = createStateResource(
-    createVorgangListResource(),
-  );
+  const vorgangStatistic: StateResource<VorgangStatistic> = createStateResource(createVorgangStatistic());
+  const searchPreviewList: StateResource<VorgangListResource> = createStateResource(createVorgangListResource());
   const searchString: string = 'searchThisForMe';
   const vorgangFilter: VorgangFilter = VorgangFilter.ALLE;
   const vorgangView: VorgangView = VorgangView.VORGANG_LIST;
 
-  const vorgangWithEingang: StateResource<VorgangWithEingangResource> = createStateResource(
-    createVorgangWithEingangResource(),
-  );
-  const attachmentList: StateResource<BinaryFileListResource> = createStateResource(
-    createBinaryFileListResource(),
-  );
-  const representationList: StateResource<BinaryFileListResource> = createStateResource(
-    createBinaryFileListResource(),
-  );
-  const assignUserCommand: StateResource<CommandResource> =
-    createStateResource(createCommandResource());
-  const forwardPendingCommand: StateResource<CommandResource> =
-    createStateResource(createCommandResource());
-  const sendPostfachNachrichtPendingCommand: StateResource<CommandResource> =
-    createStateResource(createCommandResource());
-
-  const annehmenCommand: StateResource<CommandResource> =
-    createStateResource(createCommandResource());
+  const vorgangWithEingang: StateResource<VorgangWithEingangResource> = createStateResource(createVorgangWithEingangResource());
+  const attachmentList: StateResource<BinaryFileListResource> = createStateResource(createBinaryFileListResource());
+  const representationList: StateResource<BinaryFileListResource> = createStateResource(createBinaryFileListResource());
+  const assignUserCommand: StateResource<CommandResource> = createStateResource(createCommandResource());
+  const forwardPendingCommand: StateResource<CommandResource> = createStateResource(createCommandResource());
+  const sendPostfachNachrichtPendingCommand: StateResource<CommandResource> = createStateResource(createCommandResource());
+
+  const annehmenCommand: StateResource<CommandResource> = createStateResource(createCommandResource());
   const statusCommandMap: StatusCommandMap = <any>{
     [CommandOrder.VORGANG_ANNEHMEN]: annehmenCommand,
   };
-  const revokeCommand: StateResource<CommandResource> =
-    createStateResource(createCommandResource());
+
+  const pendingCommandUri: ResourceUri = faker.internet.url();
+  const pendingCommandStateResource: StateResource<CommandResource> = createCommandStateResource();
+  const pendingCommandMap: PendingCommandMap = <any>{
+    [pendingCommandUri]: pendingCommandStateResource,
+  };
+
+  const revokeCommand: StateResource<CommandResource> = createStateResource(createCommandResource());
   const vorgangExport: StateResource<boolean> = createStateResource(false);
 
   beforeEach(() => {
@@ -106,6 +100,7 @@ describe('Vorgang Selectors', () => {
         forwardPendingCommand,
         sendPostfachNachrichtPendingCommand,
         statusCommandMap,
+        pendingCommandMap,
         revokeCommand,
         vorgangExport,
       },
@@ -113,9 +108,7 @@ describe('Vorgang Selectors', () => {
   });
 
   it('should return vorgangList', () => {
-    const result: StateResource<VorgangListResource> = VorgangSelectors.vorgangList.projector(
-      state.VorgangState,
-    );
+    const result: StateResource<VorgangListResource> = VorgangSelectors.vorgangList.projector(state.VorgangState);
 
     expect(result).toBe(vorgangList);
   });
@@ -127,9 +120,7 @@ describe('Vorgang Selectors', () => {
   });
 
   it('should return vorgangStatistic', () => {
-    const result: StateResource<VorgangStatistic> = VorgangSelectors.vorgangStatistic.projector(
-      state.VorgangState,
-    );
+    const result: StateResource<VorgangStatistic> = VorgangSelectors.vorgangStatistic.projector(state.VorgangState);
 
     expect(result).toBe(vorgangStatistic);
   });
@@ -147,9 +138,7 @@ describe('Vorgang Selectors', () => {
   });
 
   it('should return searchPreviewList', () => {
-    const result: StateResource<VorgangListResource> = VorgangSelectors.searchPreviewList.projector(
-      state.VorgangState,
-    );
+    const result: StateResource<VorgangListResource> = VorgangSelectors.searchPreviewList.projector(state.VorgangState);
 
     expect(result).toBe(searchPreviewList);
   });
@@ -172,17 +161,13 @@ describe('Vorgang Selectors', () => {
 
   describe('isVorgangViewSelected', () => {
     it('should return true if state and view matches', () => {
-      const result: boolean = VorgangSelectors.isVorgangViewSelected(
-        VorgangView.VORGANG_LIST,
-      ).projector(vorgangView);
+      const result: boolean = VorgangSelectors.isVorgangViewSelected(VorgangView.VORGANG_LIST).projector(vorgangView);
 
       expect(result).toBeTruthy();
     });
 
     it('should return false if state and view does not match', () => {
-      const result: boolean = VorgangSelectors.isVorgangViewSelected(VorgangView.NEU).projector(
-        vorgangView,
-      );
+      const result: boolean = VorgangSelectors.isVorgangViewSelected(VorgangView.NEU).projector(vorgangView);
 
       expect(result).toBeFalsy();
     });
@@ -190,9 +175,7 @@ describe('Vorgang Selectors', () => {
 
   describe('getVorgangViewRoutePath', () => {
     it('should return /alle/neu', () => {
-      const result: string = VorgangSelectors.getVorgangViewRoutePath(VorgangView.NEU).projector(
-        vorgangFilter,
-      );
+      const result: string = VorgangSelectors.getVorgangViewRoutePath(VorgangView.NEU).projector(vorgangFilter);
 
       expect(result).toBe('/alle/neu');
     });
@@ -200,16 +183,14 @@ describe('Vorgang Selectors', () => {
 
   //VorgangWithEingang
   it('should return vorgangWithEingang', () => {
-    const result: StateResource<VorgangWithEingangResource> =
-      VorgangSelectors.vorgangWithEingang.projector(state.VorgangState);
+    const result: StateResource<VorgangWithEingangResource> = VorgangSelectors.vorgangWithEingang.projector(state.VorgangState);
 
     expect(result).toBe(vorgangWithEingang);
   });
 
   describe('attachmentList', () => {
     it('should Return attachmentList from state', () => {
-      const result: StateResource<BinaryFileListResource> =
-        VorgangSelectors.attachmentList.projector(state.VorgangState);
+      const result: StateResource<BinaryFileListResource> = VorgangSelectors.attachmentList.projector(state.VorgangState);
 
       expect(result).toBe(attachmentList);
     });
@@ -217,8 +198,7 @@ describe('Vorgang Selectors', () => {
 
   describe('representationList', () => {
     it('should Return representationList from state', () => {
-      const result: StateResource<BinaryFileListResource> =
-        VorgangSelectors.representationList.projector(state.VorgangState);
+      const result: StateResource<BinaryFileListResource> = VorgangSelectors.representationList.projector(state.VorgangState);
 
       expect(result).toBe(representationList);
     });
@@ -226,8 +206,7 @@ describe('Vorgang Selectors', () => {
 
   describe('forwardPendingCommand', () => {
     it('should return command from state', () => {
-      const result: StateResource<CommandResource> =
-        VorgangSelectors.forwardPendingCommand.projector(state.VorgangState);
+      const result: StateResource<CommandResource> = VorgangSelectors.forwardPendingCommand.projector(state.VorgangState);
 
       expect(result).toBe(forwardPendingCommand);
     });
@@ -235,8 +214,9 @@ describe('Vorgang Selectors', () => {
 
   describe('send postfach command', () => {
     it('should return command from state', () => {
-      const result: StateResource<CommandResource> =
-        VorgangSelectors.sendPostfachNachrichtPendingCommand.projector(state.VorgangState);
+      const result: StateResource<CommandResource> = VorgangSelectors.sendPostfachNachrichtPendingCommand.projector(
+        state.VorgangState,
+      );
 
       expect(result).toBe(sendPostfachNachrichtPendingCommand);
     });
@@ -244,9 +224,7 @@ describe('Vorgang Selectors', () => {
 
   describe('user assign command', () => {
     it('should return command from state', () => {
-      const result: StateResource<CommandResource> = VorgangSelectors.assignUserCommand.projector(
-        state.VorgangState,
-      );
+      const result: StateResource<CommandResource> = VorgangSelectors.assignUserCommand.projector(state.VorgangState);
 
       expect(result).toBe(assignUserCommand);
     });
@@ -254,9 +232,7 @@ describe('Vorgang Selectors', () => {
 
   describe('stausCommandMap', () => {
     it('should select statusCommandMap from state', () => {
-      const result: StatusCommandMap = VorgangSelectors.statusCommandMap.projector(
-        state.VorgangState,
-      );
+      const result: StatusCommandMap = VorgangSelectors.statusCommandMap.projector(state.VorgangState);
 
       expect(result).toBe(statusCommandMap);
     });
@@ -264,9 +240,7 @@ describe('Vorgang Selectors', () => {
 
   describe('getStatusCommand', () => {
     it('should return statusCommand from state by order', () => {
-      const result: boolean = VorgangSelectors.getStatusCommand(
-        CommandOrder.VORGANG_ANNEHMEN,
-      ).projector(statusCommandMap);
+      const result: boolean = VorgangSelectors.getStatusCommand(CommandOrder.VORGANG_ANNEHMEN).projector(statusCommandMap);
 
       expect(result).toBe(annehmenCommand);
     });
@@ -274,9 +248,7 @@ describe('Vorgang Selectors', () => {
 
   describe('revokeCommand', () => {
     it('should return revokeCommand from state', () => {
-      const result: StateResource<CommandResource> = VorgangSelectors.revokeCommand.projector(
-        state.VorgangState,
-      );
+      const result: StateResource<CommandResource> = VorgangSelectors.revokeCommand.projector(state.VorgangState);
 
       expect(result).toBe(revokeCommand);
     });
@@ -284,11 +256,26 @@ describe('Vorgang Selectors', () => {
 
   describe('exportCommand', () => {
     it('should return exportCommand from state', () => {
-      const result: StateResource<boolean> = VorgangSelectors.vorgangExport.projector(
-        state.VorgangState,
-      );
+      const result: StateResource<boolean> = VorgangSelectors.vorgangExport.projector(state.VorgangState);
 
       expect(result).toBe(vorgangExport);
     });
   });
+
+  describe('pendingCommandMap', () => {
+    it('should select statusCommandMap from state', () => {
+      const result: PendingCommandMap = VorgangSelectors.pendingCommandMap.projector(state.VorgangState);
+
+      expect(result).toBe(pendingCommandMap);
+    });
+  });
+
+  describe('getPendingCommand', () => {
+    it('should return statusCommand from state by order', () => {
+      const commandStateResource: StateResource<CommandResource> =
+        VorgangSelectors.getPendingCommand(pendingCommandUri).projector(pendingCommandMap);
+
+      expect(commandStateResource).toBe(pendingCommandStateResource);
+    });
+  });
 });
diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts
index 581b6ead76..0eeceedcce 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts
@@ -25,8 +25,10 @@ import { BinaryFileListResource } from '@alfa-client/binary-file-shared';
 import { CommandOrder, CommandResource } from '@alfa-client/command-shared';
 import { EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
 import { MemoizedSelector, createFeatureSelector, createSelector } from '@ngrx/store';
+import { ResourceUri } from '@ngxp/rest';
 import { buildBackButtonUrl, buildVorgangFilterViewRoutePath } from '../vorgang-navigation.util';
 import {
+  PendingCommandMap,
   StatusCommandMap,
   VorgangFilter,
   VorgangListResource,
@@ -37,44 +39,36 @@ import {
 } from '../vorgang.model';
 import { VORGANG_FEATURE_KEY, VorgangState } from './vorgang.reducer';
 
-export const getVorgangState: MemoizedSelector<object, VorgangState> =
-  createFeatureSelector<VorgangState>(VORGANG_FEATURE_KEY);
+export const getVorgangState: MemoizedSelector<object, VorgangState> = createFeatureSelector<VorgangState>(VORGANG_FEATURE_KEY);
 
 // VorgangList
-export const vorgangList: MemoizedSelector<
-  VorgangState,
-  StateResource<VorgangListResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.vorgangList);
+export const vorgangList: MemoizedSelector<VorgangState, StateResource<VorgangListResource>> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.vorgangList,
+);
 export const vorgaenge: MemoizedSelector<VorgangState, VorgangResource[]> = createSelector(
   getVorgangState,
   (state: VorgangState) => state.vorgaenge,
 );
-export const vorgangStatistic: MemoizedSelector<
-  VorgangState,
-  StateResource<VorgangStatistic>
-> = createSelector(getVorgangState, (state: VorgangState) => state.vorgangStatistic);
-
-export const vorgangFilter = createSelector(
+export const vorgangStatistic: MemoizedSelector<VorgangState, StateResource<VorgangStatistic>> = createSelector(
   getVorgangState,
-  (state: VorgangState) => state.vorgangFilter,
+  (state: VorgangState) => state.vorgangStatistic,
 );
-export const vorgangView = createSelector(
+
+export const vorgangFilter = createSelector(getVorgangState, (state: VorgangState) => state.vorgangFilter);
+export const vorgangView = createSelector(getVorgangState, (state: VorgangState) => state.vorgangView);
+
+export const searchPreviewList: MemoizedSelector<VorgangState, StateResource<VorgangListResource>> = createSelector(
   getVorgangState,
-  (state: VorgangState) => state.vorgangView,
+  (state: VorgangState) => state.searchPreviewList,
 );
-
-export const searchPreviewList: MemoizedSelector<
-  VorgangState,
-  StateResource<VorgangListResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.searchPreviewList);
 export const searchString: MemoizedSelector<VorgangState, string> = createSelector(
   getVorgangState,
   (state: VorgangState) => state.searchString,
 );
 
-export const backButtonUrl: MemoizedSelector<VorgangState, string> = createSelector(
-  getVorgangState,
-  (state: VorgangState) => buildBackButtonUrl(state),
+export const backButtonUrl: MemoizedSelector<VorgangState, string> = createSelector(getVorgangState, (state: VorgangState) =>
+  buildBackButtonUrl(state),
 );
 
 export const isVorgangViewSelected = (view: VorgangView) =>
@@ -85,64 +79,59 @@ export const getVorgangViewRoutePath = (view: VorgangView) =>
   );
 
 export const isVorgangFilterSelected = (filter: VorgangFilter) =>
-  createSelector(
-    vorgangFilter,
-    (vorgangFilterInState: VorgangFilter) => vorgangFilterInState === filter,
-  );
+  createSelector(vorgangFilter, (vorgangFilterInState: VorgangFilter) => vorgangFilterInState === filter);
 export const getVorgangFilterRoutePath = (filter: VorgangFilter) =>
-  createSelector(
-    vorgangView,
-    searchString,
-    (vorgangViewInState: VorgangView, searchStringInState: string) =>
-      buildVorgangFilterViewRoutePath(filter, vorgangViewInState, searchStringInState),
+  createSelector(vorgangView, searchString, (vorgangViewInState: VorgangView, searchStringInState: string) =>
+    buildVorgangFilterViewRoutePath(filter, vorgangViewInState, searchStringInState),
   );
 
 //VorgangWithEingang
-export const vorgangWithEingang: MemoizedSelector<
-  VorgangState,
-  StateResource<VorgangWithEingangResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.vorgangWithEingang);
-export const attachmentList: MemoizedSelector<
-  VorgangState,
-  StateResource<BinaryFileListResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.attachmentList);
-export const representationList: MemoizedSelector<
-  VorgangState,
-  StateResource<BinaryFileListResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.representationList);
-export const forwardPendingCommand: MemoizedSelector<
-  VorgangState,
-  StateResource<CommandResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.forwardPendingCommand);
-export const sendPostfachNachrichtPendingCommand: MemoizedSelector<
-  VorgangState,
-  StateResource<CommandResource>
-> = createSelector(
+export const vorgangWithEingang: MemoizedSelector<VorgangState, StateResource<VorgangWithEingangResource>> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.vorgangWithEingang,
+);
+export const attachmentList: MemoizedSelector<VorgangState, StateResource<BinaryFileListResource>> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.attachmentList,
+);
+export const representationList: MemoizedSelector<VorgangState, StateResource<BinaryFileListResource>> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.representationList,
+);
+export const forwardPendingCommand: MemoizedSelector<VorgangState, StateResource<CommandResource>> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.forwardPendingCommand,
+);
+export const sendPostfachNachrichtPendingCommand: MemoizedSelector<VorgangState, StateResource<CommandResource>> = createSelector(
   getVorgangState,
   (state: VorgangState) => state.sendPostfachNachrichtPendingCommand,
 );
 
-export const assignUserCommand: MemoizedSelector<
-  VorgangState,
-  StateResource<CommandResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.assignUserCommand);
+export const assignUserCommand: MemoizedSelector<VorgangState, StateResource<CommandResource>> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.assignUserCommand,
+);
 
 export const statusCommandMap: MemoizedSelector<VorgangState, StatusCommandMap> = createSelector(
   getVorgangState,
   (state: VorgangState) => state.statusCommandMap,
 );
 export const getStatusCommand = (order: CommandOrder) =>
-  createSelector(
-    statusCommandMap,
-    (statusCommandMapInState: StatusCommandMap) => statusCommandMapInState[order],
-  );
+  createSelector(statusCommandMap, (statusCommandMapInState: StatusCommandMap) => statusCommandMapInState[order]);
 
-export const revokeCommand: MemoizedSelector<
-  VorgangState,
-  StateResource<CommandResource>
-> = createSelector(getVorgangState, (state: VorgangState) => state.revokeCommand);
+export const revokeCommand: MemoizedSelector<VorgangState, StateResource<CommandResource>> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.revokeCommand,
+);
 
 export const vorgangExport: MemoizedSelector<VorgangState, StateResource<boolean>> = createSelector(
   getVorgangState,
   (state: VorgangState) => state.vorgangExport,
 );
+
+export const pendingCommandMap: MemoizedSelector<VorgangState, PendingCommandMap> = createSelector(
+  getVorgangState,
+  (state: VorgangState) => state.pendingCommandMap,
+);
+export const getPendingCommand = (uri: ResourceUri) =>
+  createSelector(pendingCommandMap, (pendingCommandMapInState: PendingCommandMap) => pendingCommandMapInState[uri]);
diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts
index 5e9995262e..f272624b26 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts
@@ -36,15 +36,21 @@ import { EMPTY_STRING, StateResource, createEmptyStateResource, createStateResou
 import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
 import { HttpErrorResponse } from '@angular/common/http';
 import { faker } from '@faker-js/faker';
+import { Store } from '@ngrx/store';
 import { ResourceUri, getUrl } from '@ngxp/rest';
 import { cold, hot } from 'jest-marbles';
 import { createApiRootResource } from 'libs/api-root-shared/test/api-root';
 import { createBinaryFileListResource } from 'libs/binary-file-shared/test/binary-file';
 import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel';
-import { createCommandResource, createCreateCommandPropsWithoutResource } from 'libs/command-shared/test/command';
+import {
+  createCommandResource,
+  createCommandStateResource,
+  createCreateCommandPropsWithoutResource,
+} from 'libs/command-shared/test/command';
 import { singleColdCompleted } from 'libs/tech-shared/test/marbles';
 import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
 import { Observable, of } from 'rxjs';
+import { setPendingCommandLoading, updatePendingCommand } from './+state/vorgang.actions';
 import { VorgangFacade } from './+state/vorgang.facade';
 import { VorgangWithEingangLinkRel } from './vorgang.linkrel';
 import { AdditionalActions, VorgangResource, VorgangWithEingangResource } from './vorgang.model';
@@ -54,11 +60,13 @@ import * as VorgangNavigationUtil from './vorgang-navigation.util';
 
 describe('VorgangService', () => {
   let service: VorgangService;
+
+  let envConfig: Environment = <any>{ processorNames: ['dummyProcessorName'] };
   let navigationService: Mock<NavigationService>;
   let facade: Mock<VorgangFacade>;
   let apiRootService: Mock<ApiRootService>;
   let commandService: Mock<CommandService>;
-  let envConfig: Environment = <any>{ processorNames: ['dummyProcessorName'] };
+  let store: Mock<Store>;
 
   beforeEach(() => {
     navigationService = { ...mock(NavigationService) };
@@ -67,13 +75,15 @@ describe('VorgangService', () => {
     commandService = mock(CommandService);
     navigationService.urlChanged = jest.fn();
     navigationService.urlChanged.mockReturnValue(of({}));
+    store = mock(Store);
 
     service = new VorgangService(
+      envConfig,
       useFromMock(navigationService),
       useFromMock(facade),
       useFromMock(apiRootService),
       useFromMock(commandService),
-      envConfig,
+      useFromMock(store),
     );
   });
 
@@ -581,4 +591,87 @@ describe('VorgangService', () => {
       expect(service.reloadVorgang).toHaveBeenCalled();
     });
   });
+
+  describe('get and poll pending command', () => {
+    const resourceUri: ResourceUri = faker.internet.url();
+
+    const command: CommandResource = createCommandResource();
+    const commandStateResource: StateResource<CommandResource> = createStateResource(command);
+
+    beforeEach(() => {
+      service.selectPendingCommand = jest.fn().mockReturnValue(of(commandStateResource));
+      service._pollCommand = jest.fn().mockReturnValue(of(commandStateResource));
+    });
+
+    it('should dispatch "set pending loading" action', () => {
+      service.getAndPollPendingCommand(resourceUri);
+
+      expect(store.dispatch).toHaveBeenCalledWith(setPendingCommandLoading({ resourceUri }));
+    });
+
+    it('should call select pending command', () => {
+      service.getAndPollPendingCommand(resourceUri);
+
+      expect(service.selectPendingCommand).toHaveBeenCalledWith(resourceUri);
+    });
+
+    it('should call poll command', () => {
+      service.getAndPollPendingCommand(resourceUri).subscribe();
+
+      expect(service._pollCommand).toHaveBeenCalledWith(resourceUri, command);
+    });
+
+    it('should return value', () => {
+      const pendingCommandStateResource$: Observable<StateResource<CommandResource>> =
+        service.getAndPollPendingCommand(resourceUri);
+
+      expect(pendingCommandStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
+  });
+
+  describe('select pending command', () => {
+    const resourceUri: ResourceUri = faker.internet.url();
+    const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
+
+    beforeEach(() => {
+      store.select.mockReturnValue(of(commandStateResource));
+    });
+
+    it('should return selected value from store', () => {
+      const commandStateResource$: Observable<StateResource<CommandResource>> = service.selectPendingCommand(resourceUri);
+
+      expect(commandStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
+  });
+
+  describe('poll command', () => {
+    const resourceUri: ResourceUri = faker.internet.url();
+
+    const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]);
+    const commandStateResource: StateResource<CommandResource> = createStateResource(command);
+
+    beforeEach(() => {
+      commandService.pollCommand.mockReturnValue(of(commandStateResource));
+    });
+
+    it('should call command service', () => {
+      service._pollCommand(resourceUri, command);
+
+      expect(commandService.pollCommand).toHaveBeenCalledWith(command);
+    });
+
+    it('should dispatch "update pending command" action on command successfully done', () => {
+      service._pollCommand(resourceUri, command).subscribe();
+
+      expect(store.dispatch).toHaveBeenLastCalledWith(
+        updatePendingCommand({ relatedResourceUri: resourceUri, command: commandStateResource.resource }),
+      );
+    });
+
+    it('should return value', () => {
+      const commandStateResource$: Observable<StateResource<CommandResource>> = service._pollCommand(resourceUri, command);
+
+      expect(commandStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
+  });
 });
diff --git a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts
index 7e43262e97..f946fa0aa3 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts
@@ -36,10 +36,13 @@ import { ENVIRONMENT_CONFIG, Environment } from '@alfa-client/environment-shared
 import { NavigationService } from '@alfa-client/navigation-shared';
 import { StateResource, createEmptyStateResource, doIfLoadingRequired, isNotNull, mapToResource } from '@alfa-client/tech-shared';
 import { Inject, Injectable } from '@angular/core';
+import { Store } from '@ngrx/store';
 import { ResourceUri, hasLink } from '@ngxp/rest';
 import { Observable, combineLatest } from 'rxjs';
 import { filter, first, map, startWith, switchMap, tap, withLatestFrom } from 'rxjs/operators';
+import { setPendingCommandLoading, updatePendingCommand } from './+state/vorgang.actions';
 import { VorgangFacade } from './+state/vorgang.facade';
+import { getPendingCommand } from './+state/vorgang.selectors';
 import { buildLinkRelFromPathSegments } from './vorgang-navigation.util';
 import { VorgangWithEingangLinkRel } from './vorgang.linkrel';
 import { AdditionalActions, VorgangWithEingangResource } from './vorgang.model';
@@ -50,11 +53,12 @@ export class VorgangService {
   public static readonly VORGANG_WITH_EINGANG_URL: string = 'vorgangWithEingangUrl';
 
   constructor(
-    private navigationService: NavigationService,
-    private facade: VorgangFacade,
-    private apiRootService: ApiRootService,
-    private commandService: CommandService,
     @Inject(ENVIRONMENT_CONFIG) private envConfig: Environment,
+    private readonly navigationService: NavigationService,
+    private readonly facade: VorgangFacade,
+    private readonly apiRootService: ApiRootService,
+    private readonly commandService: CommandService,
+    private readonly store: Store,
   ) {}
 
   public getVorgangWithEingang(): Observable<StateResource<VorgangWithEingangResource>> {
@@ -220,4 +224,30 @@ export class VorgangService {
   public reloadVorgang(commandResource: CommandResource): void {
     this.facade.loadVorgangWithEingang(getEffectedResourceUrl(commandResource));
   }
+
+  public getAndPollPendingCommand(resourceUri: ResourceUri): Observable<StateResource<CommandResource>> {
+    this.store.dispatch(setPendingCommandLoading({ resourceUri }));
+    return this.selectPendingCommand(resourceUri).pipe(
+      mapToResource(),
+      switchMap((command: CommandResource) => this._pollCommand(resourceUri, command)),
+    );
+  }
+
+  public selectPendingCommand(relatedResourceUri: ResourceUri): Observable<StateResource<CommandResource>> {
+    return this.store.select(getPendingCommand(relatedResourceUri));
+  }
+
+  _pollCommand(resourceUri: ResourceUri, command: CommandResource): Observable<StateResource<CommandResource>> {
+    return this.commandService
+      .pollCommand(command)
+      .pipe(
+        tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) =>
+          this.updatePendingCommand(resourceUri, commandStateResource.resource),
+        ),
+      );
+  }
+
+  private updatePendingCommand(relatedResourceUri: ResourceUri, command: CommandResource): void {
+    this.store.dispatch(updatePendingCommand({ relatedResourceUri, command }));
+  }
 }
-- 
GitLab


From fe42994e5aa845d16b409e1823c5faff6ff0b324 Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Thu, 3 Apr 2025 19:49:29 +0200
Subject: [PATCH 6/8] OZG-7872 fix imports

---
 .../vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts    | 3 +--
 .../libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts    | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts
index e8f4098294..5b79dc4eb0 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.spec.ts
@@ -22,7 +22,7 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import { BinaryFileListResource } from '@alfa-client/binary-file-shared';
-import { CommandOrder, CommandResource } from '@alfa-client/command-shared';
+import { CommandOrder, CommandResource, PendingCommandMap } from '@alfa-client/command-shared';
 import { StateResource, createStateResource } from '@alfa-client/tech-shared';
 import { faker } from '@faker-js/faker/.';
 import { ResourceUri } from '@ngxp/rest';
@@ -35,7 +35,6 @@ import {
   createVorgangWithEingangResource,
 } from 'libs/vorgang-shared/test/vorgang';
 import {
-  PendingCommandMap,
   StatusCommandMap,
   VorgangFilter,
   VorgangListResource,
diff --git a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts
index 0eeceedcce..e8869224df 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/+state/vorgang.selectors.ts
@@ -22,13 +22,12 @@
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
 import { BinaryFileListResource } from '@alfa-client/binary-file-shared';
-import { CommandOrder, CommandResource } from '@alfa-client/command-shared';
+import { CommandOrder, CommandResource, PendingCommandMap } from '@alfa-client/command-shared';
 import { EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
 import { MemoizedSelector, createFeatureSelector, createSelector } from '@ngrx/store';
 import { ResourceUri } from '@ngxp/rest';
 import { buildBackButtonUrl, buildVorgangFilterViewRoutePath } from '../vorgang-navigation.util';
 import {
-  PendingCommandMap,
   StatusCommandMap,
   VorgangFilter,
   VorgangListResource,
-- 
GitLab


From 97506967ecfe38099e7548bf0236c58a30367533 Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Thu, 3 Apr 2025 20:27:41 +0200
Subject: [PATCH 7/8] OZG-7872 remove bescheid +state

---
 .../src/lib/+state/bescheid.facade.spec.ts    |  87 --------------
 .../src/lib/+state/bescheid.facade.ts         |  61 ----------
 .../src/lib/+state/bescheid.reducer.spec.ts   | 109 ------------------
 .../src/lib/+state/bescheid.reducer.ts        |  68 -----------
 .../src/lib/+state/bescheid.selectors.spec.ts |  53 ---------
 .../src/lib/+state/bescheid.selectors.ts      |  35 ------
 .../src/lib/bescheid-shared.module.ts         |   4 +-
 .../src/lib/bescheid.service.spec.ts          |  68 ++++++++---
 .../src/lib/bescheid.service.ts               |  37 ++++--
 9 files changed, 80 insertions(+), 442 deletions(-)
 delete mode 100644 alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.spec.ts
 delete mode 100644 alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts
 delete mode 100644 alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.spec.ts
 delete mode 100644 alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.ts
 delete mode 100644 alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.spec.ts
 delete mode 100644 alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.ts

diff --git a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.spec.ts
deleted file mode 100644
index 8de2643e5b..0000000000
--- a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.spec.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
- * Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei
- * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-import {
-  CommandOrder,
-  CommandResource,
-  CommandService,
-  CreateCommand,
-} from '@alfa-client/command-shared';
-import { createStateResource, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
-import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
-import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
-import { Store } from '@ngrx/store';
-import { Resource } from '@ngxp/rest';
-import { createCommandResource, createCreateCommand } from 'libs/command-shared/test/command';
-import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
-import { Subject } from 'rxjs';
-import { BescheidFacade } from './bescheid.facade';
-
-describe('BescheidFacade', () => {
-  const store: Mock<Store> = mock(Store);
-
-  let facade: BescheidFacade;
-  let commandService: Mock<CommandService>;
-  let selectSubj: Subject<StateResource<Resource>>;
-
-  beforeEach(() => {
-    commandService = mock(CommandService);
-
-    selectSubj = new Subject();
-    store.select.mockReturnValue(selectSubj);
-
-    facade = new BescheidFacade(useFromMock(store), useFromMock(commandService));
-  });
-
-  describe('getBescheidCommand', () => {
-    it('should return selected value', (done) => {
-      const expected: StateResource<CommandResource> = createStateResource(createCommandResource());
-
-      facade.getBescheidCommand().subscribe((userSettings) => {
-        expect(userSettings).toBe(expected);
-        done();
-      });
-
-      selectSubj.next(expected);
-    });
-  });
-
-  describe('createBescheidDraft', () => {
-    const createCommand: CreateCommand = createCreateCommand(CommandOrder.CREATE_BESCHEID);
-
-    it('should create command', () => {
-      const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource([
-        VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
-      ]);
-
-      facade.createBescheidDraft(vorgang, createCommand);
-
-      expect(commandService.createCommandByProps).toHaveBeenCalledWith({
-        resource: vorgang,
-        linkRel: VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
-        command: createCommand,
-        snackBarMessage: EMPTY_STRING,
-      });
-    });
-  });
-});
diff --git a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts
deleted file mode 100644
index 60fa7371e7..0000000000
--- a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.facade.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
- * Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei
- * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-import {
-  CommandResource,
-  CommandService,
-  CreateCommand,
-  CreateCommandProps,
-} from '@alfa-client/command-shared';
-import { EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
-import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
-import { Injectable } from '@angular/core';
-import { Store } from '@ngrx/store';
-import { Observable } from 'rxjs';
-
-import * as BescheidSelectors from './bescheid.selectors';
-
-@Injectable({ providedIn: 'root' })
-export class BescheidFacade {
-  constructor(
-    private store: Store,
-    private commandService: CommandService,
-  ) {}
-
-  public getBescheidCommand(): Observable<StateResource<CommandResource>> {
-    return this.store.select(BescheidSelectors.bescheidCommand);
-  }
-
-  public createBescheidDraft(
-    vorgangWithEingang: VorgangWithEingangResource,
-    command: CreateCommand,
-  ): void {
-    const createCommandProps: CreateCommandProps = {
-      resource: vorgangWithEingang,
-      linkRel: VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
-      command,
-      snackBarMessage: EMPTY_STRING,
-    };
-    this.commandService.createCommandByProps(createCommandProps);
-  }
-}
diff --git a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.spec.ts
deleted file mode 100644
index 35a608b282..0000000000
--- a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.spec.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
- * Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei
- * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-import { CommandOrder, CommandResource } from '@alfa-client/command-shared';
-import { ApiError, createEmptyStateResource } from '@alfa-client/tech-shared';
-import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
-import { Action } from '@ngrx/store';
-import { createCommandResource, createSuccessfullyDoneCommandStateResource } from 'libs/command-shared/test/command';
-import { createApiError } from 'libs/tech-shared/test/error';
-import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
-import { BescheidState, initialState, reducer } from './bescheid.reducer';
-
-import * as CommandActions from '../../../../command-shared/src/lib/+state/command.actions';
-
-describe('Bescheid Reducer', () => {
-  describe('unknown action', () => {
-    it('should return current state', () => {
-      const action: Action = {} as Action;
-
-      const result = reducer(initialState, action);
-
-      expect(result).toBe(initialState);
-    });
-  });
-
-  describe('bescheidCommand', () => {
-    describe('on "createCommand" action', () => {
-      it('should set resource loading', () => {
-        const resource: VorgangWithEingangResource = createVorgangWithEingangResource();
-        const action: Action = CommandActions.createCommand({
-          resource,
-          linkRel: VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
-          command: { ...createCommandResource(), order: CommandOrder.CREATE_BESCHEID },
-        });
-
-        const state: BescheidState = reducer(initialState, action);
-
-        expect(state.bescheidCommand).toEqual(createEmptyStateResource(true));
-      });
-
-      it('should replace state resource with loading', () => {
-        const initialState: BescheidState = { bescheidCommand: createSuccessfullyDoneCommandStateResource() };
-        const resource: VorgangWithEingangResource = createVorgangWithEingangResource();
-        const action: Action = CommandActions.createCommand({
-          resource,
-          linkRel: VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
-          command: { ...createCommandResource(), order: CommandOrder.CREATE_BESCHEID },
-        });
-
-        const state: BescheidState = reducer(initialState, action);
-
-        expect(state.bescheidCommand).toEqual(createEmptyStateResource(true));
-      });
-    });
-
-    describe('on "createCommandSuccess" action', () => {
-      it('should set resource', () => {
-        const command: CommandResource = {
-          ...createCommandResource(),
-          order: CommandOrder.CREATE_BESCHEID,
-        };
-        const action: Action = CommandActions.createCommandSuccess({ command });
-
-        const state: BescheidState = reducer(initialState, action);
-
-        expect(state.bescheidCommand.resource).toBe(command);
-      });
-    });
-
-    describe('on "createCommandFailure" action', () => {
-      const command: CommandResource = {
-        ...createCommandResource(),
-        order: CommandOrder.CREATE_BESCHEID,
-      };
-
-      it('should set error', () => {
-        const apiError: ApiError = createApiError();
-        const action: Action = CommandActions.createCommandFailure({
-          command,
-          error: { error: apiError },
-        });
-
-        const state: BescheidState = reducer(initialState, action);
-
-        expect(state.bescheidCommand.error).toBe(apiError);
-      });
-    });
-  });
-});
diff --git a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.ts b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.ts
deleted file mode 100644
index 870d54c9df..0000000000
--- a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.reducer.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
- * Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei
- * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-import { CommandProps, CommandResource, CreateCommandFailureProps, CreateCommandProps } from '@alfa-client/command-shared';
-import { ApiError, createEmptyStateResource, createErrorStateResource, createStateResource, StateResource, } from '@alfa-client/tech-shared';
-import { HttpErrorResponse } from '@angular/common/http';
-import { Action, ActionReducer, createReducer, on } from '@ngrx/store';
-import { isCreateBescheidCommand } from '../bescheid.util';
-
-import * as CommandActions from '../../../../command-shared/src/lib/+state/command.actions';
-
-export const BESCHEID_FEATURE_KEY = 'BescheidState';
-
-export interface BescheidPartialState {
-  readonly [BESCHEID_FEATURE_KEY]: BescheidState;
-}
-
-export interface BescheidState {
-  bescheidCommand: StateResource<CommandResource>;
-}
-
-export const initialState: BescheidState = {
-  bescheidCommand: createEmptyStateResource(),
-};
-
-const bescheidReducer: ActionReducer<BescheidState, Action> = createReducer(
-  initialState,
-  on(CommandActions.createCommand, (state: BescheidState, props: CreateCommandProps): BescheidState => {
-    return isCreateBescheidCommand(props.command.order) ? { ...state, bescheidCommand: createEmptyStateResource(true) } : state;
-  }),
-  on(CommandActions.createCommandSuccess, (state: BescheidState, props: CommandProps): BescheidState => {
-    return isCreateBescheidCommand(props.command.order) ?
-        { ...state, bescheidCommand: createStateResource(props.command) }
-      : state;
-  }),
-  on(CommandActions.createCommandFailure, (state: BescheidState, props: CreateCommandFailureProps): BescheidState => {
-    return isCreateBescheidCommand(props.command.order) ?
-        {
-          ...state,
-          bescheidCommand: createErrorStateResource(<ApiError>(<HttpErrorResponse>props.error).error),
-        }
-      : state;
-  }),
-);
-
-export function reducer(state: BescheidState, action: Action): BescheidState {
-  return bescheidReducer(state, action);
-}
diff --git a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.spec.ts
deleted file mode 100644
index d8f48a9e72..0000000000
--- a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.spec.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
- * Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei
- * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-import { CommandResource } from '@alfa-client/command-shared';
-import { createStateResource, StateResource } from '@alfa-client/tech-shared';
-import { createCommandResource } from 'libs/command-shared/test/command';
-import { BescheidPartialState, initialState } from './bescheid.reducer';
-
-import * as BescheidSelectors from './bescheid.selectors';
-
-describe('Bescheid Selectors', () => {
-  let state: BescheidPartialState;
-
-  const bescheidCommand: StateResource<CommandResource> =
-    createStateResource(createCommandResource());
-
-  beforeEach(() => {
-    state = {
-      BescheidState: {
-        ...initialState,
-        bescheidCommand,
-      },
-    };
-  });
-
-  describe('bescheidCommand', () => {
-    it('should return bescheidCommand from state', () => {
-      expect(BescheidSelectors.bescheidCommand.projector(state.BescheidState)).toEqual(
-        bescheidCommand,
-      );
-    });
-  });
-});
diff --git a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.ts b/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.ts
deleted file mode 100644
index 01f7768b4d..0000000000
--- a/alfa-client/libs/bescheid-shared/src/lib/+state/bescheid.selectors.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
- * Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei
- * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-import { CommandResource } from '@alfa-client/command-shared';
-import { StateResource } from '@alfa-client/tech-shared';
-import { createFeatureSelector, createSelector, MemoizedSelector } from '@ngrx/store';
-import { BESCHEID_FEATURE_KEY, BescheidState } from './bescheid.reducer';
-
-export const getBescheidState: MemoizedSelector<object, BescheidState> =
-  createFeatureSelector<BescheidState>(BESCHEID_FEATURE_KEY);
-
-export const bescheidCommand: MemoizedSelector<
-  BescheidState,
-  StateResource<CommandResource>
-> = createSelector(getBescheidState, (state: BescheidState) => state.bescheidCommand);
diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid-shared.module.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid-shared.module.ts
index 7c011dec93..acc61d69bf 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid-shared.module.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid-shared.module.ts
@@ -23,10 +23,8 @@
  */
 import { CommonModule } from '@angular/common';
 import { NgModule } from '@angular/core';
-import { StoreModule } from '@ngrx/store';
-import { BESCHEID_FEATURE_KEY, reducer } from './+state/bescheid.reducer';
 
 @NgModule({
-  imports: [CommonModule, StoreModule.forFeature(BESCHEID_FEATURE_KEY, reducer)],
+  imports: [CommonModule],
 })
 export class BescheidSharedModule {}
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 ae974499af..e3190c7e52 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
@@ -32,6 +32,7 @@ import {
   CommandResource,
   CommandResourceService,
   CommandService,
+  CreateCommand,
   CreateCommandProps,
   getEffectedResourceUrl,
 } from '@alfa-client/command-shared';
@@ -47,7 +48,12 @@ import {
   StateResource,
 } from '@alfa-client/tech-shared';
 import { Mock, mock } from '@alfa-client/test-utils';
-import { VorgangCommandService, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import {
+  VorgangCommandService,
+  VorgangService,
+  VorgangWithEingangLinkRel,
+  VorgangWithEingangResource,
+} from '@alfa-client/vorgang-shared';
 import { TestBed } from '@angular/core/testing';
 import { faker } from '@faker-js/faker';
 import { getUrl, LinkRel, ResourceUri } from '@ngxp/rest';
@@ -60,6 +66,7 @@ import {
   createCommandErrorStateResource,
   createCommandResource,
   createCommandStateResource,
+  createCreateCommand,
   createCreateCommandProps,
   createSuccessfullyDoneCommandStateResource,
 } from '../../../command-shared/test/command';
@@ -67,7 +74,6 @@ import { createFile } from '../../../tech-shared/test/file';
 import { singleCold, singleColdCompleted } from '../../../tech-shared/test/marbles';
 import { createBescheid, createBescheidDocument, createBescheidListResource, createBescheidResource } from '../test/bescheid';
 import { createDocumentResource } from '../test/document';
-import { BescheidFacade } from './+state/bescheid.facade';
 import { BescheidLinkRel } from './bescheid.linkrel';
 import {
   Bescheid,
@@ -95,6 +101,7 @@ import {
 } from '@alfa-client/bescheid-shared';
 import { expect } from '@jest/globals';
 import { cold } from 'jest-marbles';
+
 import * as DateUtil from '../../../tech-shared/src/lib/date.util';
 
 jest.mock('@alfa-client/bescheid-shared', () => {
@@ -112,7 +119,6 @@ jest.mock('@alfa-client/bescheid-shared', () => {
 
 describe('BescheidService', () => {
   let service: BescheidService;
-  let facade: Mock<BescheidFacade>;
   let vorgangService: Mock<VorgangService>;
   let resourceRepository: Mock<ResourceRepository>;
   let commandService: Mock<CommandService>;
@@ -129,7 +135,6 @@ describe('BescheidService', () => {
   const commandStateResource: StateResource<CommandResource> = createCommandStateResource();
 
   beforeEach(() => {
-    facade = mock(BescheidFacade);
     resourceRepository = mock(ResourceRepository);
     commandService = mock(CommandService);
     vorgangCommandService = mock(VorgangCommandService);
@@ -144,7 +149,6 @@ describe('BescheidService', () => {
 
     TestBed.configureTestingModule({
       providers: [
-        { provide: BescheidFacade, useValue: facade },
         { provide: VorgangService, useValue: vorgangService },
         { provide: ResourceRepository, useValue: resourceRepository },
         { provide: CommandService, useValue: commandService },
@@ -676,25 +680,22 @@ describe('BescheidService', () => {
 
   describe('createBescheid', () => {
     const vorgangWithEingang: VorgangWithEingangResource = createVorgangWithEingangResource();
+
     const command: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]);
     const commandStateResource: StateResource<CommandResource> = createStateResource(command);
 
-    beforeEach(() => {
-      service.updateBescheidDraft = jest.fn();
-    });
+    const bescheid: Bescheid = createBescheid();
 
     beforeEach(() => {
-      facade.getBescheidCommand.mockReturnValue(of(commandStateResource));
+      service.updateBescheidDraft = jest.fn();
+      service._createBescheidDraft = jest.fn().mockReturnValue(of(commandStateResource));
       (service as any).bescheidResourceService.loadByResourceUri = jest.fn();
     });
 
-    it('should call facade', () => {
-      service.createBescheid(vorgangWithEingang).subscribe();
+    it('should call create bescheid draft', () => {
+      service.createBescheid(vorgangWithEingang, bescheid).subscribe();
 
-      expect(facade.createBescheidDraft).toHaveBeenCalledWith(vorgangWithEingang, {
-        order: CommandOrder.CREATE_BESCHEID,
-        body: null,
-      });
+      expect(service._createBescheidDraft).toHaveBeenCalledWith(vorgangWithEingang, bescheid);
     });
 
     it('should update bescheid draft', () => {
@@ -702,6 +703,43 @@ describe('BescheidService', () => {
 
       expect(service.updateBescheidDraft).toHaveBeenCalledWith(commandStateResource.resource);
     });
+
+    it('should return value', () => {
+      const commandStateResource$: Observable<StateResource<CommandResource>> = service.createBescheid(vorgangWithEingang);
+
+      expect(commandStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
+  });
+
+  describe('create bescheid draft', () => {
+    const createCommand: CreateCommand = createCreateCommand(CommandOrder.CREATE_BESCHEID);
+    const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource());
+
+    beforeEach(() => {
+      commandService.createCommandByProps.mockReturnValue(of(commandStateResource));
+    });
+
+    it('should call command service', () => {
+      const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource([
+        VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
+      ]);
+
+      service._createBescheidDraft(vorgang);
+
+      expect(commandService.createCommandByProps).toHaveBeenCalledWith({
+        resource: vorgang,
+        linkRel: VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
+        command: createCommand,
+        snackBarMessage: EMPTY_STRING,
+      });
+    });
+
+    it('should return created command', () => {
+      const commandStateResource$: Observable<StateResource<CommandResource>> =
+        service._createBescheidDraft(vorgangWithEingangResource);
+
+      expect(commandStateResource$).toBeObservable(singleColdCompleted(commandStateResource));
+    });
   });
 
   describe('updateBescheidDraft', () => {
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 22107e92d9..18e048dcf2 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
@@ -54,6 +54,7 @@ import {
   CommandOrder,
   CommandResource,
   CommandService,
+  CreateCommandProps,
   getEffectedResourceUrl,
   notHasCommandError,
   tapOnCommandSuccessfullyDone,
@@ -62,6 +63,7 @@ import { PostfachService } from '@alfa-client/postfach-shared';
 import {
   createEmptyStateResource,
   createStateResource,
+  EMPTY_STRING,
   filterIsLoadedOrHasError,
   getEmbeddedResources,
   hasStateResourceError,
@@ -72,17 +74,20 @@ import {
   sortByGermanDateStr,
   StateResource,
 } from '@alfa-client/tech-shared';
-import { VorgangCommandService, VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import {
+  VorgangCommandService,
+  VorgangService,
+  VorgangWithEingangLinkRel,
+  VorgangWithEingangResource,
+} from '@alfa-client/vorgang-shared';
 import { inject, Injectable } from '@angular/core';
 import { getUrl, hasLink, LinkRel, Resource, ResourceUri } from '@ngxp/rest';
 import { isNil } from 'lodash-es';
 import { BehaviorSubject, filter, first, map, Observable, startWith, switchMap } from 'rxjs';
-import { BescheidFacade } from './+state/bescheid.facade';
 import { DocumentLinkRel } from './document.linkrel';
 
 @Injectable({ providedIn: 'root' })
 export class BescheidService {
-  private readonly bescheidFacade = inject(BescheidFacade);
   private readonly commandService = inject(CommandService);
   private readonly vorgangCommandService = inject(VorgangCommandService);
   private readonly binaryFileService = inject(BinaryFileService);
@@ -263,14 +268,24 @@ export class BescheidService {
     vorgangWithEingang: VorgangWithEingangResource,
     bescheid?: Bescheid,
   ): Observable<StateResource<CommandResource>> {
-    this.bescheidFacade.createBescheidDraft(vorgangWithEingang, buildCreateBescheidCommand(bescheid));
-    return this.bescheidFacade
-      .getBescheidCommand()
-      .pipe(
-        tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) =>
-          this.updateBescheidDraft(commandStateResource.resource),
-        ),
-      );
+    return this._createBescheidDraft(vorgangWithEingang, bescheid).pipe(
+      tapOnCommandSuccessfullyDone((commandStateResource: StateResource<CommandResource>) =>
+        this.updateBescheidDraft(commandStateResource.resource),
+      ),
+    );
+  }
+
+  _createBescheidDraft(
+    vorgangWithEingang: VorgangWithEingangResource,
+    bescheid?: Bescheid,
+  ): Observable<StateResource<CommandResource>> {
+    const createCommandProps: CreateCommandProps = {
+      resource: vorgangWithEingang,
+      linkRel: VorgangWithEingangLinkRel.CREATE_BESCHEID_DRAFT,
+      command: buildCreateBescheidCommand(bescheid),
+      snackBarMessage: EMPTY_STRING,
+    };
+    return this.commandService.createCommandByProps(createCommandProps);
   }
 
   updateBescheidDraft(command: CommandResource): void {
-- 
GitLab


From 79399215a27d6bdb1924af75543b106b74931b28 Mon Sep 17 00:00:00 2001
From: Martin <git@mail.de>
Date: Fri, 4 Apr 2025 08:53:58 +0200
Subject: [PATCH 8/8] OZG-7872 adjust tests

---
 .../+state/loesch-anforderung.effects.spec.ts | 30 ++++++++-----------
 .../+state/loesch-anforderung.reducer.spec.ts | 30 +++++++++----------
 2 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.effects.spec.ts b/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.effects.spec.ts
index 5f02e52761..90525b88b6 100644
--- a/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.effects.spec.ts
+++ b/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.effects.spec.ts
@@ -21,24 +21,25 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
-import { TestBed } from '@angular/core/testing';
 import {
   COMMAND_ERROR_MESSAGES,
   CommandErrorMessage,
   CommandOrder,
   CommandResource,
+  CreateCommandProps,
 } from '@alfa-client/command-shared';
 import { NavigationService } from '@alfa-client/navigation-shared';
 import { ApiError } from '@alfa-client/tech-shared';
 import { Mock, mock } from '@alfa-client/test-utils';
 import { SnackBarService } from '@alfa-client/ui';
 import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
+import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
+import { TestBed } from '@angular/core/testing';
 import { provideMockActions } from '@ngrx/effects/testing';
 import { Action } from '@ngrx/store';
 import { provideMockStore } from '@ngrx/store/testing';
 import { cold, hot } from 'jest-marbles';
-import { createCommandResource } from 'libs/command-shared/test/command';
+import { createCommandResource, createCreateCommandProps } from 'libs/command-shared/test/command';
 import { createApiError, createHttpErrorResponse } from 'libs/tech-shared/test/error';
 import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
 import { Observable, of } from 'rxjs';
@@ -131,7 +132,8 @@ describe('LoeschAnforderungEffects', () => {
       ...createCommandResource(),
       order: CommandOrder.VORGANG_LOESCHEN,
     };
-    const action = CommandActions.createCommandSuccess({ command });
+    const createCommandProps: CreateCommandProps = createCreateCommandProps();
+    const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
     it('should call sncakbarService on vorgangLoeschen command', () => {
       actions = of(action);
@@ -143,17 +145,14 @@ describe('LoeschAnforderungEffects', () => {
   });
 
   describe('loeschAnforderungZuruecknehmenFailedAndReloadVorgangSuccess', () => {
-    const action =
-      LoeschAnforderungActions.loeschAnforderungZuruecknehmenFailedAndReloadVorgangSuccess();
+    const action = LoeschAnforderungActions.loeschAnforderungZuruecknehmenFailedAndReloadVorgangSuccess();
 
     it('should show snackbar', () => {
       actions = of(action);
 
       effects.loeschAnforderungZuruecknehmenFailedAndReloadVorgangSuccess$.subscribe();
 
-      expect(snackbarService.showError).toHaveBeenCalledWith(
-        COMMAND_ERROR_MESSAGES[CommandErrorMessage.CONCURRENT_MODIFICATION],
-      );
+      expect(snackbarService.showError).toHaveBeenCalledWith(COMMAND_ERROR_MESSAGES[CommandErrorMessage.CONCURRENT_MODIFICATION]);
     });
   });
 
@@ -164,20 +163,17 @@ describe('LoeschAnforderungEffects', () => {
     };
     const actionError = <HttpErrorResponse>{ error };
     const overviewUrl: string = faker.internet.url();
-    const action =
-      LoeschAnforderungActions.loeschAnforderungZuruecknehmenFailedAndReloadVorgangFailure({
-        error: actionError,
-        overviewUrl,
-      });
+    const action = LoeschAnforderungActions.loeschAnforderungZuruecknehmenFailedAndReloadVorgangFailure({
+      error: actionError,
+      overviewUrl,
+    });
 
     it('should show snackbar', () => {
       actions = of(action);
 
       effects.loeschAnforderungZuruecknehmenFailedAndReloadVorgangFailure$.subscribe();
 
-      expect(snackbarService.showInfo).toHaveBeenCalledWith(
-        'Der Vorgang wurde zwischenzeitlich gelöscht.',
-      );
+      expect(snackbarService.showInfo).toHaveBeenCalledWith('Der Vorgang wurde zwischenzeitlich gelöscht.');
     });
 
     it('should navigate to overview', () => {
diff --git a/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.reducer.spec.ts b/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.reducer.spec.ts
index 5a25e85bc3..4ea2d3ff41 100644
--- a/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.reducer.spec.ts
+++ b/alfa-client/libs/loesch-anforderung-shared/src/lib/+state/loesch-anforderung.reducer.spec.ts
@@ -21,16 +21,11 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { CommandOrder, CommandResource } from '@alfa-client/command-shared';
-import {
-  ApiError,
-  createEmptyStateResource,
-  createErrorStateResource,
-  createStateResource,
-} from '@alfa-client/tech-shared';
+import { CommandOrder, CommandResource, CreateCommandProps } from '@alfa-client/command-shared';
+import { ApiError, createEmptyStateResource, createErrorStateResource, createStateResource } from '@alfa-client/tech-shared';
 import { VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
 import { Action } from '@ngrx/store';
-import { createCommand, createCommandResource } from 'libs/command-shared/test/command';
+import { createCommand, createCommandResource, createCreateCommandProps } from 'libs/command-shared/test/command';
 import { createLoeschAnforderungResource } from 'libs/loesch-anforderung-shared/test/loesch-anforderung';
 import { createApiError } from 'libs/tech-shared/test/error';
 import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
@@ -100,7 +95,8 @@ describe('LoeschAnforderung Reducer', () => {
           ...createCommandResource(),
           order: CommandOrder.VORGANG_ZUM_LOESCHEN_MARKIEREN,
         };
-        const action = CommandActions.createCommandSuccess({ command });
+        const createCommandProps: CreateCommandProps = createCreateCommandProps();
+        const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
         const state: LoeschAnforderungState = reducer(initialState, action);
 
@@ -150,7 +146,8 @@ describe('LoeschAnforderung Reducer', () => {
           ...createCommandResource(),
           order: CommandOrder.VORGANG_LOESCHEN,
         };
-        const action = CommandActions.createCommandSuccess({ command });
+        const createCommandProps: CreateCommandProps = createCreateCommandProps();
+        const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
         const state: LoeschAnforderungState = reducer(initialState, action);
 
@@ -180,7 +177,8 @@ describe('LoeschAnforderung Reducer', () => {
           ...createCommandResource(),
           order: CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN,
         };
-        const action = CommandActions.createCommandSuccess({ command });
+        const createCommandProps: CreateCommandProps = createCreateCommandProps();
+        const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
         const state: LoeschAnforderungState = reducer(initialState, action);
 
@@ -192,7 +190,8 @@ describe('LoeschAnforderung Reducer', () => {
           ...createCommandResource(),
           order: CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN,
         };
-        const action = CommandActions.createCommandSuccess({ command });
+        const createCommandProps: CreateCommandProps = createCreateCommandProps();
+        const action = CommandActions.createCommandSuccess({ command, createCommandProps });
 
         const state: LoeschAnforderungState = reducer(
           {
@@ -213,13 +212,12 @@ describe('LoeschAnforderung Reducer', () => {
           order: CommandOrder.LOESCH_ANFORDERUNG_ZURUECKNEHMEN,
         };
         const error: ApiError = createApiError();
-        const action = CommandActions.createCommandFailure({ command, error });
+        const createCommandProps: CreateCommandProps = createCreateCommandProps();
+        const action = CommandActions.createCommandFailure({ command, createCommandProps, error });
 
         const state: LoeschAnforderungState = reducer(initialState, action);
 
-        expect(state.loeschAnforderungZuruecknehmenCommand).toEqual(
-          createErrorStateResource(error),
-        );
+        expect(state.loeschAnforderungZuruecknehmenCommand).toEqual(createErrorStateResource(error));
       });
     });
 
-- 
GitLab