From 5e9593a01a5635cf67841fcd3103665283f2afd8 Mon Sep 17 00:00:00 2001
From: RIHTARSIC Joze <joze.rihtarsic@ext.ec.europa.eu>
Date: Thu, 16 Nov 2023 08:17:54 +0100
Subject: [PATCH] Synchronize create payload version

---
 .../src/app/common/model/document-ro.model.ts |  4 +--
 .../resource-document-panel.component.html    | 25 ++++++++-----
 .../resource-document-panel.component.ts      |  3 ++
 .../subresource-document-panel.component.html | 11 ++++--
 .../subresource-document-panel.component.ts   |  3 ++
 .../smp/data/model/doc/DBDocument.java        |  5 ++-
 .../ec/edelivery/smp/data/ui/DocumentRo.java  | 10 ++++++
 .../smp/services/ui/UIDocumentService.java    | 35 +++++++++----------
 .../smp/data/dao/DocumentDaoTest.java         | 10 +++---
 .../smp/data/dao/ResourceDaoTest.java         |  8 +++--
 .../edelivery/smp/data/dao/TestUtilsDao.java  | 15 +++++---
 11 files changed, 81 insertions(+), 48 deletions(-)

diff --git a/smp-angular/src/app/common/model/document-ro.model.ts b/smp-angular/src/app/common/model/document-ro.model.ts
index 883637f9b..737e367c0 100644
--- a/smp-angular/src/app/common/model/document-ro.model.ts
+++ b/smp-angular/src/app/common/model/document-ro.model.ts
@@ -1,6 +1,3 @@
-import {SearchTableEntity} from '../search-table/search-table-entity.model';
-import {VisibilityEnum} from "../enums/visibility.enum";
-
 export interface DocumentRo {
   mimeType?: string;
   name?: string;
@@ -8,6 +5,7 @@ export interface DocumentRo {
   currentResourceVersion?:number;
   allVersions?: number[];
   payloadVersion?:number;
+  payloadCreatedOn?: Date;
   payload?:string;
 }
 
diff --git a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html
index b9fe7cda7..742b828e9 100644
--- a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html
+++ b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.html
@@ -35,20 +35,29 @@
       <div [formGroup]="documentForm"
            style="float: right;  vertical-align:middle;display: flex;align-items: center;justify-content: center; gap:0.4em;padding-right: 10px">
         <span style="font-size: 0.8em">Show version:</span>
-        <select matNativeControl style="width: 100px; border-bottom: gray solid 1px"
-                    placeholder="All document version"
-                    matTooltip="Select version to display."
-                    formControlName="payloadVersion"
-                    id="document version_id"
-                    (change)="onSelectionDocumentVersionChanged()"
+        <select matNativeControl style="width: 100px; border-bottom: grey solid 1px"
+                placeholder="All document version"
+                matTooltip="Select version to display."
+                formControlName="payloadVersion"
+                id="document version_id"
+                (change)="onSelectionDocumentVersionChanged()"
         >
           <option *ngFor="let version of getDocumentVersions"
-                      [value]="version"
+                  [value]="version"
           >
             {{version}}
           </option>
-
         </select>
+
+        <span style="font-size: 0.8em">Created on:</span>
+          <input id="payloadCreatedOn_id"
+                 matInput [ngxMatDatetimePicker]="payloadCreatedOnPicker"
+                 formControlName="payloadCreatedOn"
+                 readonly>
+          <mat-datepicker-toggle matSuffix [for]="payloadCreatedOnPicker" style="visibility: hidden"></mat-datepicker-toggle>
+          <ngx-mat-datetime-picker #payloadCreatedOnPicker [showSpinners]="true" [showSeconds]="false"
+                                   [hideTime]="false"></ngx-mat-datetime-picker>
+
       </div>
     </mat-toolbar-row>
   </mat-toolbar>
diff --git a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts
index 7170580c8..5f05b7db9 100644
--- a/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts
+++ b/smp-angular/src/app/edit/edit-resources/resource-document-panel/resource-document-panel.component.ts
@@ -56,6 +56,7 @@ export class ResourceDocumentPanelComponent implements AfterViewInit, BeforeLeav
       'mimeType': new FormControl({value: null}),
       'name': new FormControl({value: null}),
       'currentResourceVersion': new FormControl({value: null}),
+      'payloadCreatedOn': new FormControl({value: null}),
       'payloadVersion': new FormControl({value: null}),
       'payload': new FormControl({value: null}),
     });
@@ -109,6 +110,7 @@ export class ResourceDocumentPanelComponent implements AfterViewInit, BeforeLeav
       this.documentForm.controls['name'].setValue(value.name);
       this.documentForm.controls['currentResourceVersion'].setValue(value.currentResourceVersion);
       this.documentForm.controls['payloadVersion'].setValue(value.payloadVersion);
+      this.documentForm.controls['payloadCreatedOn'].setValue(value.payloadCreatedOn);
       this.documentForm.controls['payload'].setValue(!value.payload?"":value.payload);
       this.documentForm.controls['payload'].enable();
       // the method documentVersionsExists already uses the current value to check if versions exists
@@ -122,6 +124,7 @@ export class ResourceDocumentPanelComponent implements AfterViewInit, BeforeLeav
       this.documentForm.controls['payload'].setValue("");
       this.documentForm.controls['currentResourceVersion'].setValue("");
       this.documentForm.controls['payloadVersion'].setValue("");
+      this.documentForm.controls['payloadCreatedOn'].setValue("");
       this.documentForm.controls['payload'].setValue("");
     }
     this.documentForm.markAsPristine();
diff --git a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html
index 58b1b31df..28843f1c6 100644
--- a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html
+++ b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.html
@@ -33,7 +33,7 @@
       <div [formGroup]="documentForm"
            style="float: right;  vertical-align:middle;display: flex;align-items: center;justify-content: center; gap:0.4em;padding-right: 10px">
         <span style="font-size: 0.8em">Show version:</span>
-        <select matNativeControl style="width: 100px; border-bottom: gray solid 1px"
+        <select matNativeControl style="width: 100px; border-bottom: grey solid 1px"
                     placeholder="All document version"
                     matTooltip="Select version to display."
                     formControlName="payloadVersion"
@@ -45,8 +45,15 @@
           >
             {{version}}
           </option>
-
         </select>
+        <span style="font-size: 0.8em">Created on:</span>
+        <input id="payloadCreatedOn_id"
+               matInput [ngxMatDatetimePicker]="payloadCreatedOnPicker"
+               formControlName="payloadCreatedOn"
+               readonly>
+        <mat-datepicker-toggle matSuffix [for]="payloadCreatedOnPicker" style="visibility: hidden"></mat-datepicker-toggle>
+        <ngx-mat-datetime-picker #payloadCreatedOnPicker [showSpinners]="true" [showSeconds]="false"
+                                 [hideTime]="false"></ngx-mat-datetime-picker>
       </div>
     </mat-toolbar-row>
   </mat-toolbar>
diff --git a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts
index fd17488e3..45c692add 100644
--- a/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts
+++ b/smp-angular/src/app/edit/edit-resources/subresource-document-panel/subresource-document-panel.component.ts
@@ -72,6 +72,7 @@ export class SubresourceDocumentPanelComponent implements AfterViewInit, BeforeL
       'name': new FormControl({value: null}),
       'currentResourceVersion': new FormControl({value: null}),
       'payloadVersion': new FormControl({value: null}),
+      'payloadCreatedOn': new FormControl({value: null}),
       'payload': new FormControl({value: null}),
     });
     this.documentForm.controls['payload'].setValue("")
@@ -145,6 +146,7 @@ export class SubresourceDocumentPanelComponent implements AfterViewInit, BeforeL
       this.documentForm.controls['name'].setValue(value.name);
       this.documentForm.controls['currentResourceVersion'].setValue(value.currentResourceVersion);
       this.documentForm.controls['payloadVersion'].setValue(value.payloadVersion);
+      this.documentForm.controls['payloadCreatedOn'].setValue(value.payloadCreatedOn);
       this.documentForm.controls['payload'].setValue(!value.payload?"":value.payload);
       this.documentForm.controls['payload'].enable();
 
@@ -159,6 +161,7 @@ export class SubresourceDocumentPanelComponent implements AfterViewInit, BeforeL
       this.documentForm.controls['payload'].setValue("");
       this.documentForm.controls['currentResourceVersion'].setValue("");
       this.documentForm.controls['payloadVersion'].setValue("");
+      this.documentForm.controls['payloadCreatedOn'].setValue("");
       this.documentForm.controls['payload'].setValue("");
     }
     this.documentForm.markAsPristine();
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java
index 03d4c6ab1..54e056371 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocument.java
@@ -103,10 +103,9 @@ public class DBDocument extends BaseEntity {
 
     protected int getNextVersionIndex(){
         List<DBDocumentVersion> list = getDocumentVersions();
-        return  list.stream()
+        return list.stream()
                 .map(DBDocumentVersion::getVersion)
-                .reduce(-1, (a, b) -> Integer.max(a, b))
-                .intValue() + 1;
+                .reduce(0, (a, b) -> Integer.max(a, b)) + 1;
     }
 
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DocumentRo.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DocumentRo.java
index b85cb38ea..82aef876a 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DocumentRo.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/DocumentRo.java
@@ -1,5 +1,6 @@
 package eu.europa.ec.edelivery.smp.data.ui;
 
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -12,6 +13,7 @@ public class DocumentRo {
     String name;
     Integer payloadVersion;
     String payload;
+    OffsetDateTime payloadCreatedOn;
 
     public String getDocumentId() {
         return documentId;
@@ -67,4 +69,12 @@ public class DocumentRo {
     public void setPayload(String payload) {
         this.payload = payload;
     }
+
+    public OffsetDateTime getPayloadCreatedOn() {
+        return payloadCreatedOn;
+    }
+
+    public void setPayloadCreatedOn(OffsetDateTime payloadCreatedOn) {
+        this.payloadCreatedOn = payloadCreatedOn;
+    }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDocumentService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDocumentService.java
index 6cac6bc47..853831eea 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDocumentService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIDocumentService.java
@@ -78,32 +78,25 @@ public class UIDocumentService {
         RequestData data = resourceHandlerService.buildRequestDataForResource(domainResourceDef.getDomain(),
                 resource, null);
 
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        ResponseData responseData = new SpiResponseData(bos);
-        try {
-            resourceHandler.generateResource(data, responseData, Collections.emptyList());
-        } catch (ResourceException e) {
-            throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "StoreResourceValidation", ExceptionUtils.getRootCauseMessage(e));
-        }
-        String genDoc = new String(bos.toByteArray());
-        LOG.info("Generate document [{}]", genDoc);
-        DocumentRo result = new DocumentRo();
-        result.setPayload(genDoc);
-        return result;
+        return getDocumentRo(resourceHandler, data);
     }
 
     @Transactional
     public DocumentRo generateDocumentForSubresource(Long subresourceId, Long resourceId, DocumentRo documentRo) {
         LOG.info("Generate document");
         DBResource parentEntity = resourceDao.find(resourceId);
-        DBSubresource enitity = subresourceDao.find(subresourceId);
-        DBSubresourceDef subresourceDef = enitity.getSubresourceDef();
+        DBSubresource entity = subresourceDao.find(subresourceId);
+        DBSubresourceDef subresourceDef = entity.getSubresourceDef();
 
         ResourceHandlerSpi resourceHandler = resourceHandlerService.getSubresourceHandler(subresourceDef, subresourceDef.getResourceDef());
 
         RequestData data = resourceHandlerService.buildRequestDataForSubResource(parentEntity.getDomainResourceDef().getDomain(),
-                parentEntity, enitity);
+                parentEntity, entity);
+
+        return getDocumentRo(resourceHandler, data);
+    }
 
+    private DocumentRo getDocumentRo(ResourceHandlerSpi resourceHandler, RequestData data) {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         ResponseData responseData = new SpiResponseData(bos);
         try {
@@ -111,7 +104,7 @@ public class UIDocumentService {
         } catch (ResourceException e) {
             throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "StoreResourceValidation", ExceptionUtils.getRootCauseMessage(e));
         }
-        String genDoc = new String(bos.toByteArray());
+        String genDoc = bos.toString();
         LOG.info("Generate document [{}]", genDoc);
         DocumentRo result = new DocumentRo();
         result.setPayload(genDoc);
@@ -163,9 +156,9 @@ public class UIDocumentService {
      * return version, if version does not exists return current version. if current version does not exists
      * return last version
      *
-     * @param resourceId
-     * @param version
-     * @return
+     * @param resourceId resource id of the document
+     * @param version   version of the payload for the document
+     * @return DocumentRo with payload and version
      */
     @Transactional
     public DocumentRo getDocumentForResource(Long resourceId, int version) {
@@ -198,6 +191,9 @@ public class UIDocumentService {
         documentVersion.setVersion(version + 1);
         documentVersion.setDocument(document);
         documentVersion.setContent(baos.toByteArray());
+        // to get the current persist time
+        documentVersion.prePersist();
+
         document.getDocumentVersions().add(documentVersion);
         document.setCurrentVersion(documentVersion.getVersion());
         return convert(document, documentVersion);
@@ -231,6 +227,7 @@ public class UIDocumentService {
         documentRo.setName(document.getName());
         documentRo.setCurrentResourceVersion(document.getCurrentVersion());
         if (version != null) {
+            documentRo.setPayloadCreatedOn(version.getCreatedOn());
             documentRo.setPayloadVersion(version.getVersion());
             documentRo.setPayload(new String(version.getContent()));
         }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDaoTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDaoTest.java
index b8b936dd6..755ab86f7 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDaoTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDaoTest.java
@@ -29,7 +29,7 @@ public class DocumentDaoTest extends AbstractBaseDao {
 
         assertNotNull(document.getId());
         assertEquals(2, document.getDocumentVersions().size());
-        assertEquals(1, document.getCurrentVersion());
+        assertEquals(2, document.getCurrentVersion());
     }
 
 
@@ -40,7 +40,7 @@ public class DocumentDaoTest extends AbstractBaseDao {
         assertTrue(result.isPresent());
         assertEquals(testUtilsDao.getDocumentD1G1RD1(), result.get());
         // the default setup  createResources  sets two versions (0 and 1 ) with current version 1
-        assertEquals(1, result.get().getCurrentVersion());
+        assertEquals(2, result.get().getCurrentVersion());
     }
 
 
@@ -58,7 +58,7 @@ public class DocumentDaoTest extends AbstractBaseDao {
 
         assertTrue(result.isPresent());
         // the default setup  createResources  sets two versions (0 and 1 ) with current version 1
-        assertEquals(1, result.get().getVersion());
+        assertEquals(2, result.get().getVersion());
         assertEquals(testUtilsDao.getDocumentD1G1RD1().getDocumentVersions().get(1), result.get());
     }
 
@@ -76,8 +76,8 @@ public class DocumentDaoTest extends AbstractBaseDao {
         Optional<DBDocumentVersion> result = testInstance.getCurrentDocumentVersionForSubresource(testUtilsDao.getSubresourceD1G1RD1_S1());
 
         assertTrue(result.isPresent());
-        // the default setup  createResources  sets two versions (0 and 1 ) with current version 1
-        assertEquals(1, result.get().getVersion());
+        // the default setup  createResources  sets two versions (1 and 2 ) with current version 2
+        assertEquals(2, result.get().getVersion());
         assertEquals(testUtilsDao.getDocumentD1G1RD1_S1().getDocumentVersions().get(1), result.get());
     }
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoTest.java
index 83804441f..d476a2bfa 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoTest.java
@@ -63,16 +63,18 @@ public class ResourceDaoTest extends AbstractBaseDao {
         Assert.assertTrue(optResult.isPresent());
         Assert.assertNotNull(optResult.get().getDocument());
         Assert.assertNotNull(optResult.get().getDocument().getId());
-        Assert.assertEquals(0, optResult.get().getDocument().getCurrentVersion());
+        Assert.assertEquals(1, optResult.get().getDocument().getCurrentVersion());
         Assert.assertEquals(1, optResult.get().getDocument().getDocumentVersions().size());
         Assert.assertNotNull(optResult.get().getDocument().getDocumentVersions().get(0).getId());
-        Assert.assertEquals(0, optResult.get().getDocument().getDocumentVersions().get(0).getVersion());
+        Assert.assertEquals(1, optResult.get().getDocument().getDocumentVersions().get(0).getVersion());
     }
 
     @Test
     @Transactional
     public void persistNewVersionToResourceWithDocument() {
-        Optional<DBResource> optResource = testInstance.getResource(TEST_SG_ID_1, TEST_SG_SCHEMA_1, testUtilsDao.getResourceDefSmp(), testUtilsDao.getD1());
+        Optional<DBResource> optResource = testInstance.getResource(TEST_SG_ID_1, TEST_SG_SCHEMA_1,
+                testUtilsDao.getResourceDefSmp(), testUtilsDao.getD1());
+        Assert.assertTrue(optResource.isPresent());
         DBResource resource = testInstance.find(optResource.get().getId());
 
         int docCount = resource.getDocument().getDocumentVersions().size();
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
index b2e474925..98f10a2bd 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
@@ -25,6 +25,8 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 
+import java.util.Optional;
+
 import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*;
 import static eu.europa.ec.edelivery.smp.testutil.TestDBUtils.*;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -248,9 +250,15 @@ public class TestUtilsDao {
 
     @Transactional
     public void deactivateUser(String username) {
-        DBUser user = userDao.findUserByUsername(username).get();
+        Optional<DBUser> userOpt = userDao.findUserByUsername(username);
+        if (!userOpt.isPresent()) {
+            LOG.warn("User [{}] not found and cannot be deactivated!", username);
+            return;
+        }
+        DBUser user = userOpt.get();
         user.setActive(false);
         persistFlushDetach(user);
+
     }
 
 
@@ -490,7 +498,7 @@ public class TestUtilsDao {
             assertNotNull(document.getDocumentVersions().get(i).getId());
         }
         // current version is the last version
-        assertEquals(versions-1, document.getCurrentVersion());
+        assertEquals(versions, document.getCurrentVersion());
 
         return document;
     }
@@ -615,9 +623,6 @@ public class TestUtilsDao {
         return memEManager.find(clazz, id);
     }
 
-
-
-
     public void clear() {
         memEManager.clear();
     }
-- 
GitLab