From 1a8be398db4244adb1d8ae3e8934d9974e79a8f1 Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Thu, 12 Dec 2024 13:06:27 +0100
Subject: [PATCH] OZG-6989-7280 archive service

---
 .../command-shared/src/lib/command.model.ts   |  1 +
 ...nfirmation-dialog-container.component.html |  4 +-
 ...rmation-dialog-container.component.spec.ts | 44 ++++++---
 ...confirmation-dialog-container.component.ts | 27 +++---
 .../src/lib/vorgang.service.spec.ts           | 95 +++++++------------
 .../vorgang-shared/src/lib/vorgang.service.ts | 15 ++-
 6 files changed, 95 insertions(+), 91 deletions(-)

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 50b3d13dfa..a64cb0dd5f 100644
--- a/alfa-client/libs/command-shared/src/lib/command.model.ts
+++ b/alfa-client/libs/command-shared/src/lib/command.model.ts
@@ -87,6 +87,7 @@ export enum CommandOrder {
   CREATE_BESCHEID_DOCUMENT = 'CREATE_BESCHEID_DOCUMENT',
   SEND_BESCHEID = 'SEND_BESCHEID',
   CREATE_COLLABORATION_REQUEST = 'CREATE_COLLABORATION_REQUEST',
+  ARCHIVE_VORGANG = 'ARCHIVE_VORGANG',
 }
 
 export interface CreateCommandProps {
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.html
index 7841dbaf5d..df26f4a900 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.html
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.html
@@ -1,4 +1,6 @@
 <alfa-vorgang-archive-confirmation-dialog
   (confirmationButtonClicked)="onConfirmationButtonClicked()"
   (cancelButtonClicked)="onCancelButtonClicked()"
-/>
\ No newline at end of file
+/>
+
+<ng-container *ngIf="archiveSubscription$ | async"/>
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.spec.ts
index daa41d9a53..d1b55b2e99 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.spec.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.spec.ts
@@ -1,16 +1,19 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
+import { CommandResource, isSuccessfulDone } from '@alfa-client/command-shared';
 import { createStateResource, StateResource } from '@alfa-client/tech-shared';
 import { mock } from '@alfa-client/test-utils';
 import { VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
 import { DialogRef } from '@angular/cdk/dialog';
 import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang';
 import { MockComponent } from 'ng-mocks';
-import { describe } from 'node:test';
 import { of } from 'rxjs';
+import { createCommandResource } from '../../../../../../../command-shared/test/command';
 import { VorgangArchiveConfirmationDialogContainerComponent } from './vorgang-archive-confirmation-dialog-container.component';
 import { VorgangArchiveConfirmationDialogComponent } from './vorgang-archive-confirmation-dialog/vorgang-archive-confirmation-dialog.component';
 
+jest.mock('@alfa-client/command-shared');
+
 describe('VorgangArchiveConfirmationDialogContainerComponent', () => {
   let component: VorgangArchiveConfirmationDialogContainerComponent;
   let fixture: ComponentFixture<VorgangArchiveConfirmationDialogContainerComponent>;
@@ -49,17 +52,9 @@ describe('VorgangArchiveConfirmationDialogContainerComponent', () => {
   });
 
   describe('component', () => {
-    describe('ngOnInit', () => {
-      it('should get archive', () => {
-        component.ngOnInit();
-
-        expect(vorgangService.getVorgangArchive).toHaveBeenCalled();
-      });
-    });
-
     describe('archiveDoneHandler', () => {
-      it('should close dialog if archive is done', () => {
-        component.archiveDoneHandler(vorgangArchiveState);
+      it('should close dialog', () => {
+        component.archiveDoneHandler();
 
         expect(dialogRef.close).toHaveBeenCalled();
       });
@@ -74,11 +69,36 @@ describe('VorgangArchiveConfirmationDialogContainerComponent', () => {
     });
 
     describe('onConfirmationButtonClicked', () => {
-      it('should archive vorgang', () => {
+      const commandState: StateResource<CommandResource> = createStateResource(createCommandResource());
+
+      beforeEach(() => {
+        component.archiveDoneHandler = jest.fn();
+        vorgangService.archive.mockReturnValue(of(commandState));
+      });
+
+      it('should call vorgangService archive', () => {
         component.onConfirmationButtonClicked();
 
         expect(vorgangService.archive).toHaveBeenCalledWith(vorgangWithEingang);
       });
+
+      it('should call archiveDoneHandler if command was successfull', () => {
+        (isSuccessfulDone as jest.Mock).mockReturnValue(true);
+
+        component.onConfirmationButtonClicked();
+        component.archiveSubscription$.subscribe();
+
+        expect(component.archiveDoneHandler).toHaveBeenCalled();
+      });
+
+      it('should not call archiveDoneHandler if command was not successfull', () => {
+        (isSuccessfulDone as jest.Mock).mockReturnValue(false);
+
+        component.onConfirmationButtonClicked();
+        component.archiveSubscription$.subscribe();
+
+        expect(component.archiveDoneHandler).not.toHaveBeenCalled();
+      });
     });
   });
 });
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.ts
index 480855deff..01a663163e 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-more-menu/vorgang-archive-container/vorgang-archive-confirmation-dialog-container/vorgang-archive-confirmation-dialog-container.component.ts
@@ -1,7 +1,8 @@
-import { StateResource } from '@alfa-client/tech-shared';
+import { CommandResource, isSuccessfulDone } from '@alfa-client/command-shared';
+import { mapToResource } from '@alfa-client/tech-shared';
 import { VorgangService, VorgangWithEingangResource } from '@alfa-client/vorgang-shared';
 import { DialogRef } from '@angular/cdk/dialog';
-import { Component, inject, OnInit } from '@angular/core';
+import { Component, inject } from '@angular/core';
 import { Observable, tap } from 'rxjs';
 import { VorgangArchiveConfirmationDialogData } from './vorgang-archive-confirmation-dialog/vorgang-archive-confirmation-dialog.model';
 
@@ -9,22 +10,15 @@ import { VorgangArchiveConfirmationDialogData } from './vorgang-archive-confirma
   selector: 'alfa-vorgang-archive-confirmation-dialog-container',
   templateUrl: './vorgang-archive-confirmation-dialog-container.component.html',
 })
-export class VorgangArchiveConfirmationDialogContainerComponent implements OnInit {
+export class VorgangArchiveConfirmationDialogContainerComponent {
   private vorgangService = inject(VorgangService);
   private dialogRef = inject(DialogRef<unknown, VorgangArchiveConfirmationDialogData>);
 
   private vorgangWithEingang: VorgangWithEingangResource = this.dialogRef.config.data.vorgangWithEingang;
+  public archiveSubscription$: Observable<CommandResource>;
 
-  public archiveStateResource$: Observable<StateResource<boolean>>;
-
-  ngOnInit(): void {
-    this.archiveStateResource$ = this.vorgangService
-      .getVorgangArchive()
-      .pipe(tap((vorgangArchiveStateResource) => this.archiveDoneHandler(vorgangArchiveStateResource)));
-  }
-
-  archiveDoneHandler(vorgangArchiveStateResource: StateResource<boolean>): void {
-    if (vorgangArchiveStateResource.resource) this.dialogRef.close();
+  archiveDoneHandler(): void {
+    this.dialogRef.close();
   }
 
   public onCancelButtonClicked(): void {
@@ -32,6 +26,11 @@ export class VorgangArchiveConfirmationDialogContainerComponent implements OnIni
   }
 
   public onConfirmationButtonClicked(): void {
-    this.vorgangService.archive(this.vorgangWithEingang);
+    this.archiveSubscription$ = this.vorgangService.archive(this.vorgangWithEingang).pipe(
+      mapToResource(),
+      tap((command: CommandResource) => {
+        if (isSuccessfulDone(command)) this.archiveDoneHandler();
+      }),
+    );
   }
 }
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 fb38b27192..ab91899911 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
@@ -23,20 +23,10 @@
  */
 import { ApiRootLinkRel, ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared';
 import { BinaryFileListResource } from '@alfa-client/binary-file-shared';
-import {
-  CommandOrder,
-  CommandResource,
-  CommandService,
-  CreateCommandProps,
-} from '@alfa-client/command-shared';
+import { CommandOrder, CommandResource, CommandService, CreateCommandProps } from '@alfa-client/command-shared';
 import { Environment } from '@alfa-client/environment-shared';
 import { NavigationService } from '@alfa-client/navigation-shared';
-import {
-  EMPTY_STRING,
-  StateResource,
-  createEmptyStateResource,
-  createStateResource,
-} from '@alfa-client/tech-shared';
+import { EMPTY_STRING, StateResource, createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared';
 import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
 import { HttpErrorResponse } from '@angular/common/http';
 import { ResourceUri, getUrl } from '@ngxp/rest';
@@ -82,12 +72,10 @@ describe('VorgangService', () => {
   });
 
   const vorgangWithEingang: VorgangWithEingangResource = createVorgangWithEingangResource();
-  const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> =
-    createStateResource(vorgangWithEingang);
+  const vorgangWithEingangStateResource: StateResource<VorgangWithEingangResource> = createStateResource(vorgangWithEingang);
 
   describe('getVorgangWithEingang', () => {
-    const apiRootStateResource: StateResource<ApiRootResource> =
-      createStateResource(createApiRootResource());
+    const apiRootStateResource: StateResource<ApiRootResource> = createStateResource(createApiRootResource());
 
     beforeEach(() => {
       apiRootService.getApiRoot.mockReturnValue(of(apiRootStateResource));
@@ -108,17 +96,13 @@ describe('VorgangService', () => {
     describe('initial', () => {
       beforeEach(() => {
         apiRootService.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource }));
-        facade.getVorgangWithEingang.mockReturnValue(
-          hot('-a', { a: vorgangWithEingangStateResource }),
-        );
+        facade.getVorgangWithEingang.mockReturnValue(hot('-a', { a: vorgangWithEingangStateResource }));
       });
 
       it('should return value', () => {
         const vorgangList = service.getVorgangWithEingang();
 
-        expect(vorgangList).toBeObservable(
-          cold('ab', { a: createEmptyStateResource(true), b: vorgangWithEingangStateResource }),
-        );
+        expect(vorgangList).toBeObservable(cold('ab', { a: createEmptyStateResource(true), b: vorgangWithEingangStateResource }));
       });
     });
 
@@ -145,16 +129,13 @@ describe('VorgangService', () => {
     it('should call facade', () => {
       service.getVorgangWithEingangUri();
 
-      expect(navigationService.getDecodedParam).toHaveBeenCalledWith(
-        VorgangService.VORGANG_WITH_EINGANG_URL,
-      );
+      expect(navigationService.getDecodedParam).toHaveBeenCalledWith(VorgangService.VORGANG_WITH_EINGANG_URL);
     });
   });
 
   describe('getAttachments', () => {
     const binaryFile: BinaryFileListResource = createBinaryFileListResource();
-    const binaryFileStateResource: StateResource<BinaryFileListResource> =
-      createStateResource(binaryFile);
+    const binaryFileStateResource: StateResource<BinaryFileListResource> = createStateResource(binaryFile);
 
     beforeEach(() => {
       facade.getAttachmentList.mockReturnValue(of(binaryFileStateResource));
@@ -182,9 +163,7 @@ describe('VorgangService', () => {
       it('should return value', () => {
         const vorgangList = service.getAttachments();
 
-        expect(vorgangList).toBeObservable(
-          cold('ab', { a: createEmptyStateResource(true), b: binaryFileStateResource }),
-        );
+        expect(vorgangList).toBeObservable(cold('ab', { a: createEmptyStateResource(true), b: binaryFileStateResource }));
       });
     });
 
@@ -215,8 +194,7 @@ describe('VorgangService', () => {
 
   describe('getRepresentations', () => {
     const binaryFile: BinaryFileListResource = createBinaryFileListResource();
-    const binaryFileStateResource: StateResource<BinaryFileListResource> =
-      createStateResource(binaryFile);
+    const binaryFileStateResource: StateResource<BinaryFileListResource> = createStateResource(binaryFile);
 
     beforeEach(() => {
       facade.getRepresentationList.mockReturnValue(of(binaryFileStateResource));
@@ -244,9 +222,7 @@ describe('VorgangService', () => {
       it('should return value', () => {
         const vorgangList = service.getRepresentations();
 
-        expect(vorgangList).toBeObservable(
-          cold('ab', { a: createEmptyStateResource(true), b: binaryFileStateResource }),
-        );
+        expect(vorgangList).toBeObservable(cold('ab', { a: createEmptyStateResource(true), b: binaryFileStateResource }));
       });
     });
 
@@ -305,8 +281,7 @@ describe('VorgangService', () => {
   });
 
   describe('setPendingForwardSingleCommand', () => {
-    const commandStateResource: StateResource<CommandResource> =
-      createStateResource(createCommandResource());
+    const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource());
 
     it('should call facade', () => {
       service.setPendingForwardSingleCommand(commandStateResource);
@@ -337,8 +312,7 @@ describe('VorgangService', () => {
   });
 
   describe('setPendingForwardSingleCommand', () => {
-    const commandStateResource: StateResource<CommandResource> =
-      createStateResource(createCommandResource());
+    const commandStateResource: StateResource<CommandResource> = createStateResource(createCommandResource());
 
     it('should call facade', () => {
       service.setPendingForwardSingleCommand(commandStateResource);
@@ -355,9 +329,7 @@ describe('VorgangService', () => {
     it('should call navigation service', () => {
       service.reloadCurrentVorgang();
 
-      expect(navigationService.getDecodedParam).toHaveBeenCalledWith(
-        VorgangService.VORGANG_WITH_EINGANG_URL,
-      );
+      expect(navigationService.getDecodedParam).toHaveBeenCalledWith(VorgangService.VORGANG_WITH_EINGANG_URL);
     });
 
     it('should call loadVorgangWithEingang', () => {
@@ -380,9 +352,7 @@ describe('VorgangService', () => {
     it('should call navigation service', () => {
       service.reloadCurrentVorgangWithAddtionalActions(additionalActions);
 
-      expect(navigationService.getDecodedParam).toHaveBeenCalledWith(
-        VorgangService.VORGANG_WITH_EINGANG_URL,
-      );
+      expect(navigationService.getDecodedParam).toHaveBeenCalledWith(VorgangService.VORGANG_WITH_EINGANG_URL);
     });
 
     it('should call loadVorgangWithEingangWithAdditionalActions', () => {
@@ -391,10 +361,7 @@ describe('VorgangService', () => {
 
       service.reloadCurrentVorgangWithAddtionalActions(additionalActions);
 
-      expect(facade.loadVorgangWithEingangWithAdditionalActions).toHaveBeenCalledWith(
-        vorgangUri,
-        additionalActions,
-      );
+      expect(facade.loadVorgangWithEingangWithAdditionalActions).toHaveBeenCalledWith(vorgangUri, additionalActions);
     });
   });
 
@@ -423,9 +390,7 @@ describe('VorgangService', () => {
     it('should call facade', () => {
       service.reloadVorgang(command);
 
-      expect(facade.loadVorgangWithEingang).toHaveBeenCalledWith(
-        getUrl(command, CommandLinkRel.EFFECTED_RESOURCE),
-      );
+      expect(facade.loadVorgangWithEingang).toHaveBeenCalledWith(getUrl(command, CommandLinkRel.EFFECTED_RESOURCE));
     });
   });
 
@@ -493,6 +458,20 @@ describe('VorgangService', () => {
     });
   });
 
+  describe('archive', () => {
+    it('should call commandService createCommandByProps', () => {
+      service.archive(vorgangWithEingang);
+
+      const expectedProps = {
+        resource: vorgangWithEingang,
+        linkRel: VorgangWithEingangLinkRel.ARCHIVE,
+        command: { order: CommandOrder.ARCHIVE_VORGANG, body: {} },
+        snackBarMessage: 'Vorgang in Archivierung.',
+      };
+      expect(commandService.createCommandByProps).toHaveBeenCalledWith(expectedProps);
+    });
+  });
+
   describe('processVorgang', () => {
     const vorgangWithEingang: VorgangWithEingangResource = createVorgangWithEingangResource();
     const command: CommandResource = createCommandResource();
@@ -518,8 +497,7 @@ describe('VorgangService', () => {
     });
 
     it('should return command', () => {
-      const processVorgangCommand: Observable<StateResource<CommandResource>> =
-        service.processVorgang(vorgangWithEingang);
+      const processVorgangCommand: Observable<StateResource<CommandResource>> = service.processVorgang(vorgangWithEingang);
 
       expect(processVorgangCommand).toBeObservable(cold('a', { a: commandStateResource }));
     });
@@ -531,11 +509,10 @@ describe('VorgangService', () => {
 
       service.setAktenzeichen(vorgangWithEingang, aktenzeichen);
 
-      expect(commandService.createCommand).toHaveBeenCalledWith(
-        vorgangWithEingang,
-        VorgangWithEingangLinkRel.SET_AKTENZEICHEN,
-        { order: CommandOrder.SET_AKTENZEICHEN, body: { aktenzeichen } },
-      );
+      expect(commandService.createCommand).toHaveBeenCalledWith(vorgangWithEingang, VorgangWithEingangLinkRel.SET_AKTENZEICHEN, {
+        order: CommandOrder.SET_AKTENZEICHEN,
+        body: { aktenzeichen },
+      });
     });
   });
 });
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 7b525a7b6e..1af6e12ff7 100644
--- a/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts
+++ b/alfa-client/libs/vorgang-shared/src/lib/vorgang.service.ts
@@ -35,7 +35,7 @@ import { NavigationService } from '@alfa-client/navigation-shared';
 import { StateResource, createEmptyStateResource, doIfLoadingRequired, isNotNull } from '@alfa-client/tech-shared';
 import { Inject, Injectable } from '@angular/core';
 import { ResourceUri, hasLink } from '@ngxp/rest';
-import { Observable, combineLatest, of } from 'rxjs';
+import { Observable, combineLatest } from 'rxjs';
 import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators';
 import { VorgangFacade } from './+state/vorgang.facade';
 import { buildLinkRelFromPathSegments } from './vorgang-navigation.util';
@@ -168,12 +168,17 @@ export class VorgangService {
     this.facade.export(vorgangWithEingang);
   }
 
-  public getVorgangArchive(): Observable<StateResource<boolean>> {
-    return of(createEmptyStateResource<boolean>());
+  public archive(vorgangWithEingang: VorgangWithEingangResource): Observable<StateResource<CommandResource>> {
+    return this.commandService.createCommandByProps(this.createVorgangArchiveCommandProps(vorgangWithEingang));
   }
 
-  public archive(vorgangWithEingang: VorgangWithEingangResource): Observable<StateResource<CommandResource>> {
-    return of(createEmptyStateResource<CommandResource>());
+  private createVorgangArchiveCommandProps(vorgangWithEingang: VorgangWithEingangResource): CreateCommandProps {
+    return {
+      resource: vorgangWithEingang,
+      linkRel: VorgangWithEingangLinkRel.ARCHIVE,
+      command: { order: CommandOrder.ARCHIVE_VORGANG, body: {} },
+      snackBarMessage: 'Vorgang in Archivierung.',
+    };
   }
 
   public processVorgang(vorgangWithEingang: VorgangWithEingangResource): Observable<StateResource<CommandResource>> {
-- 
GitLab