瀏覽代碼

model 1.0.8

Dalibor Votruba 4 年之前
父節點
當前提交
ecfee469fc
共有 43 個文件被更改,包括 730 次插入193 次删除
  1. 91 9
      @Database/bo_create_schema.sql
  2. 134 110
      @Documentation/BlueprintOptimizer.simp
  3. 14 1
      AppServer/Business/Services/Base/UserContextService.cs
  4. 13 7
      AppServer/Business/Services/CatalogueService.cs
  5. 56 0
      AppServer/Business/Services/ConfigurationService.cs
  6. 3 1
      AppServer/Business/Services/DocumentService.cs
  7. 4 5
      AppServer/Business/Services/UserService.cs
  8. 5 2
      AppServer/Business/Services/WorkspaceService.cs
  9. 45 5
      AppServer/Connector.Console/Connection.cs
  10. 80 1
      AppServer/Connector/AbstractConnection.cs
  11. 86 20
      AppServer/Data/Entity/BOContext.cs
  12. 38 0
      AppServer/Data/Entity/BOContext.decl.cs
  13. 1 1
      AppServer/Data/Entity/BillingInfo.cs
  14. 3 1
      AppServer/Data/Entity/BillingPlan.cs
  15. 1 1
      AppServer/Data/Entity/Invoice.cs
  16. 1 1
      AppServer/Data/Entity/InvoiceIssuer.cs
  17. 1 1
      AppServer/Data/Entity/InvoiceItem.cs
  18. 1 1
      AppServer/Data/Entity/Metadocument.cs
  19. 8 3
      AppServer/Data/Entity/MetadocumentBilling.cs
  20. 1 1
      AppServer/Data/Entity/MimeType.cs
  21. 19 0
      AppServer/Data/Entity/Registration.cs
  22. 9 0
      AppServer/Data/Entity/Registration.decl.cs
  23. 1 1
      AppServer/Data/Entity/Statistic.cs
  24. 1 1
      AppServer/Data/Entity/StatusHistory.cs
  25. 1 1
      AppServer/Data/Entity/Structure.cs
  26. 1 1
      AppServer/Data/Entity/Tag.cs
  27. 1 1
      AppServer/Data/Entity/User.cs
  28. 3 1
      AppServer/Data/Entity/User.decl.cs
  29. 14 0
      AppServer/Data/Entity/UserWorkspace.decl.cs
  30. 4 2
      AppServer/Data/Entity/Workspace.cs
  31. 4 2
      AppServer/Data/Entity/Workspace.decl.cs
  32. 1 0
      AppServer/Data/Entity/WorkspaceBilling.cs
  33. 10 0
      AppServer/Data/Entity/WorkspaceBilling.decl.cs
  34. 14 0
      AppServer/Data/Repository/RegistrationRepo.cs
  35. 14 3
      AppServer/Data/Repository/WorkspaceRepo.cs
  36. 24 1
      AppServer/Data/readme.txt
  37. 3 3
      AppServer/Web/Services/ConsoleController.cs
  38. 11 0
      AppServer/Web/Startup.cs
  39. 1 1
      AppServer/Web/appsettings.Development.json
  40. 1 1
      AppServer/Web/appsettings.json
  41. 1 0
      Common/qdr.fnd.core.business/AbstractService.cs
  42. 1 1
      Common/qdr.fnd.core.data.itfc/Repository/IDaoRepository.cs
  43. 5 2
      Common/qdr.fnd.core.data/Repository/EntityRepository.cs

+ 91 - 9
@Database/bo_create_schema.sql

@@ -1,4 +1,4 @@
--- 12.8.2021 1.0.6
+-- 18.8.2021 1.0.8
 -- Table User --------------------------
 --Defines User identity with statistics informations. Defines if user is enabled and/or user is system account also.
 CREATE TABLE [dbo].[User]
@@ -54,6 +54,15 @@ GO
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'User identity with properties' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'User'
 GO
 
+-- Indexes of table User ------------------------------
+CREATE UNIQUE INDEX IDX_IFREFERENCE ON [dbo].[User]
+(IFReference) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+GO
+
+CREATE UNIQUE INDEX IDX_USER_NAME ON [dbo].[User]
+(Name) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+GO
+
 
 -- Table UserWorkspace --------------------------
 --Association between User and Workspace. Which Workspace is assigned to user.
@@ -84,7 +93,7 @@ CREATE TABLE [dbo].[Workspace]
 (
     [Id] [bigint] NOT NULL IDENTITY (1, 1),
     [Name] [nvarchar] (200) NOT NULL,
-    [BillingInfoId] [bigint] NOT NULL,
+    [BillingInfoId] [bigint] NULL,
     [BillingPlanId] [bigint] NOT NULL,
     [APIKey] [uniqueidentifier] NOT NULL CONSTRAINT DF_Workspace_APIKey DEFAULT newid(),
     [APIPassword] [nvarchar] (50) NOT NULL,
@@ -593,13 +602,18 @@ GO
 --Association of metadocument and billing plan
 CREATE TABLE [dbo].[MetadocumentBilling]
 (
-    [MetadocumentId] [bigint] NOT NULL,
-    [BillingPlanId] [bigint] NOT NULL,
+    [MetadocumentId] [bigint] NULL,
+    [WorkspaceBillingId] [bigint] NOT NULL,
     [CreditCost] [int] NOT NULL CONSTRAINT DF_MetadocumentBilling_CreditCost DEFAULT 0,
     [Watermark] [bit] NOT NULL CONSTRAINT DF_MetadocumentBilling_Watermark DEFAULT 0,
     [Quality] [int] NOT NULL CONSTRAINT DF_MetadocumentBilling_Quality DEFAULT 0,
     [ProcessProfile] [varchar] (5) NULL,
     [Test] [bit] NOT NULL CONSTRAINT DF_MetadocumentBilling_Test DEFAULT 0,
+    [Procesed] [datetime] NULL,
+    [ProcessStart] [datetime] NULL,
+    [Downloaded] [datetime] NULL,
+    [ProcessState] [int] NOT NULL,
+    [PSInstance] [varchar] (100) NULL,
     [Created] [datetime] NOT NULL CONSTRAINT DF_MetadocumentBilling_Created DEFAULT getdate(),
     [Modified] [datetime] NULL
 )
@@ -608,7 +622,7 @@ GO
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Reference to owning metadocument' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'MetadocumentId'
 GO
 
-EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Reference to billing plan' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'BillingPlanId'
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Reference to workspace billing plan' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'WorkspaceBillingId'
 GO
 
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Numeric value of billing plan spending. Depends on BillingPlan.' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'CreditCost'
@@ -626,13 +640,28 @@ GO
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Flag if testing mode' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'Test'
 GO
 
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp when document was processed' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'Procesed'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp when document set to processing state' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'ProcessStart'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp when document was last downloaded' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'Downloaded'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Last state of processing (OK,Fail)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'ProcessState'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Process server instance identifier' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'PSInstance'
+GO
+
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp when billing was created' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'Created'
 GO
 
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp when billing was modified' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling', @level2type=N'COLUMN',@level2name=N'Modified'
 GO
 
-EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Association of metadocument and billing plan' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling'
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Association of metadocument and billing plan with properties. Stores information about processed documents (name, status timestamps, etc.) relates to workspace billing plan selection.' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'MetadocumentBilling'
 GO
 
 
@@ -640,6 +669,7 @@ GO
 --Deffines current state of billing plan for workspace
 CREATE TABLE [dbo].[WorkspaceBilling]
 (
+    [Id] [bigint] NOT NULL IDENTITY (1, 1),
     [WorkspaceId] [bigint] NOT NULL,
     [BillingPlanId] [bigint] NOT NULL,
     [Created] [datetime] NOT NULL CONSTRAINT DF_WorkspaceBilling_Created DEFAULT getdate(),
@@ -651,10 +681,14 @@ CREATE TABLE [dbo].[WorkspaceBilling]
     [CustomPSTWatermark] [bit] NOT NULL CONSTRAINT DF_WorkspaceBilling_CustomPSTWatermark DEFAULT 0,
     [CustomPSTQuality] [int] NOT NULL CONSTRAINT DF_WorkspaceBilling_CustomPSTQuality DEFAULT 0,
     [CustomPSTProcessProfile] [varchar] (5) NULL,
-    [CustomPSTTest] [bit] NOT NULL CONSTRAINT DF_WorkspaceBilling_CustomPSTTest DEFAULT 0
+    [CustomPSTTest] [bit] NOT NULL CONSTRAINT DF_WorkspaceBilling_CustomPSTTest DEFAULT 0,
+    CONSTRAINT PK_WORKSPACE_BILLINGPLAN_ID PRIMARY KEY (Id)	
 )
 GO
 
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Primary key of WorkspaceBilling record' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'WorkspaceBilling', @level2type=N'COLUMN',@level2name=N'Id'
+GO
+
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Reference to owning workspace' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'WorkspaceBilling', @level2type=N'COLUMN',@level2name=N'WorkspaceId'
 GO
 
@@ -1036,6 +1070,54 @@ GO
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Holds statistics information on daily base' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Statistic'
 GO
 
+-- Indexes of table Statistic ------------------------------
+CREATE UNIQUE INDEX IDX_DATE ON [dbo].[Statistic]
+(Year,Month,Day) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+GO
+
+
+-- Table Registration --------------------------
+CREATE TABLE [dbo].[Registration]
+(
+    [Id] [bigint] NOT NULL IDENTITY (1, 1),
+    [PSInstance] [varchar] (100) NULL,
+    [LocationIP] [varchar] (100) NULL,
+    [LastActivity] [datetime] NULL,
+    [DocumentProcessedCnt] [int] NOT NULL,
+    [DocumentFailedCnt] [int] NOT NULL,
+    [Created] [datetime] NOT NULL CONSTRAINT DF_Registration_Created DEFAULT getdate(),
+    [Modified] [datetime] NULL,
+    CONSTRAINT OK_REGISTRATION_ID PRIMARY KEY (Id)	
+)
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Primary key of Registration record' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'Id'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Process server instance identifier' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'PSInstance'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Process server instance identifier' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'LocationIP'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp latest activity' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'LastActivity'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'# of new processed documents' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'DocumentProcessedCnt'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'# of failed documents' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'DocumentFailedCnt'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp when registration was created' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'Created'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Timestamp when registration was modified' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration', @level2type=N'COLUMN',@level2name=N'Modified'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Holds Process Server registrations' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Registration'
+GO
+
 
 
 -- References for UserWorkspace --------------------------
@@ -1125,7 +1207,7 @@ GO
 ALTER TABLE [dbo].[MetadocumentBilling]
 ADD 
     CONSTRAINT REL_MetadocumentBilling_Metadocument FOREIGN KEY (MetadocumentId) REFERENCES [dbo].[Metadocument] (Id), 
-    CONSTRAINT REL_MetadocumentBilling_BillingPlan FOREIGN KEY (BillingPlanId) REFERENCES [dbo].[BillingPlan] (Id)
+    CONSTRAINT REL_MetadocumentBilling_WorkspaceBilling FOREIGN KEY (WorkspaceBillingId) REFERENCES [dbo].[WorkspaceBilling] (Id)
 GO
 
 -- References for WorkspaceBilling --------------------------
@@ -1160,5 +1242,5 @@ ADD
     CONSTRAINT REL_InvoiceIssuer_User_Modified FOREIGN KEY (ModifiedByUserId) REFERENCES [dbo].[User] (Id)
 GO
 
-EXEC sys.sp_updateextendedproperty @name=N'BO_Version', @value=N'1.0.6'
+EXEC sys.sp_updateextendedproperty @name=N'BO_Version', @value=N'1.0.8'
 GO

+ 134 - 110
@Documentation/BlueprintOptimizer.simp

@@ -9,7 +9,7 @@
     <entity-names>
       <counter>
         <item-type type-id="erd-entity" type="Entity" />
-        <value>18</value>
+        <value>19</value>
       </counter>
       <counter>
         <item-type type-id="cnd-user" type="User" />
@@ -147,11 +147,11 @@
     <entity-ids>
       <counter>
         <item-type type-id="group" type="Group" />
-        <value>3923</value>
+        <value>4075</value>
       </counter>
       <counter>
         <item-type type-id="erd-entity" type="Entity" />
-        <value>19</value>
+        <value>20</value>
       </counter>
       <counter>
         <item-type type-id="cnd-user" type="User" />
@@ -203,7 +203,7 @@
       </counter>
       <counter>
         <item-type type-id="erd-relationship" type="Relationship" />
-        <value>60</value>
+        <value>66</value>
       </counter>
       <counter>
         <item-type type-id="ui-area" type="Area" />
@@ -367,7 +367,7 @@
     <fields>
       <counter>
         <type>SoftwareIdeasModeler.Core.DiagramItems.Erd.ErdEntityAttribute</type>
-        <value>231</value>
+        <value>246</value>
       </counter>
       <counter>
         <type>SoftwareIdeasModeler.Core.DiagramItems.Erd.ErdEntityIndex</type>
@@ -724,7 +724,7 @@
           </documentation>
           <abstract-items />
           <sub-models />
-          <diagram type="entity-relationship" id="pca974f586cd54eb2957d89ec61c4843d_762498462" name="BOServer" order-index="0" uid="" show-id="false" show-name="true" show-parent-name="false" name-style="local-auto-parents" show-stereotypes="true" show-tagged-values="false" show-template-parameters="true" show-fields="true" show-field-tags="true" show-empty-compartments="true" show-special-indicators="false" show-rules="true" show-attributes="true" show-attribute-visibility="true" show-operations="true" show-operation-parameters="true" show-operation-visibility="true" show-visibility-sign="true" show-nullability="true" show-sequence-number="false" show-extension-points="false" show-relationship-texts="true" show-data="true" show-description="false" show-field-description="false" auto-routed-paths="false" default-line-style="default" default-type-set="MSSQL" view-location="901,469">
+          <diagram type="entity-relationship" id="pca974f586cd54eb2957d89ec61c4843d_762498462" name="BOServer" order-index="0" uid="" show-id="false" show-name="true" show-parent-name="false" name-style="local-auto-parents" show-stereotypes="true" show-tagged-values="false" show-template-parameters="true" show-fields="true" show-field-tags="true" show-empty-compartments="true" show-special-indicators="false" show-rules="true" show-attributes="true" show-attribute-visibility="true" show-operations="true" show-operation-parameters="true" show-operation-visibility="true" show-visibility-sign="true" show-nullability="true" show-sequence-number="false" show-extension-points="false" show-relationship-texts="true" show-data="true" show-description="false" show-field-description="false" auto-routed-paths="false" default-line-style="default" default-type-set="MSSQL" view-location="1502,-6">
             <style>
               <background-color index="1" color="#FFFFFFFF" />
               <background-color index="2" color="#FFFFFFFF" />
@@ -736,9 +736,9 @@
               </authors>
               <description>AppServer database model</description>
               <creation-date>07/26/2021 15:41:20</creation-date>
-              <change-date>08/02/2021 08:20:06</change-date>
+              <change-date>08/17/2021 09:26:32</change-date>
               <revision-count>0</revision-count>
-              <version>1.0.7.</version>
+              <version>1.0.8.</version>
             </meta>
             <documentation>
               <text>
@@ -1095,7 +1095,7 @@
                 <attributes>
                   <attribute uid="a7dde6800c37940389459c8caf8b01322535" cid="ELEM014" name="Id" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="false" primary-key="true" nullable="false" description="Workspace primary key" default-value="" auto-increment="true" creation-date="07/27/2021 05:37:32" />
                   <attribute uid="ae5aa34dfd38f4a4eb0e6d7cffa4d0b5c913" cid="ELEM015" name="Name" type="nvarchar" type-id="MsSql.nvarchar" type-size="200" foreign-key="false" primary-key="false" nullable="false" description="Workspace name" default-value="" auto-increment="false" creation-date="07/27/2021 05:38:27" />
-                  <attribute uid="a496263d90bf347b99c6ee14a5044ee26898" cid="ELEM026" name="BillingInfoId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Reference to current billing info record" default-value="" auto-increment="false" creation-date="07/27/2021 06:03:38" />
+                  <attribute uid="a496263d90bf347b99c6ee14a5044ee26898" cid="ELEM026" name="BillingInfoId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="true" description="Reference to current billing info record" default-value="" auto-increment="false" creation-date="07/27/2021 06:03:38" />
                   <attribute uid="af6b373e37760465b901a02daa2115dee68" cid="ELEM092" name="BillingPlanId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Reference to current billing plan record" default-value="" auto-increment="false" creation-date="07/27/2021 08:24:31" />
                   <attribute uid="a5837b2881cc04111aac3df09439d6e43297" cid="ELEM115" name="APIKey" type="uniqueidentifier" type-id="MsSql.uniqueidentifier" type-size="" foreign-key="false" primary-key="false" nullable="false" description="API Key for access to workspace via B2B interface" default-value="newid()" auto-increment="false" creation-date="07/27/2021 19:44:05">
                     <documentation>
@@ -2331,17 +2331,6 @@
                       </style>
                     </default>
                     <styles />
-                    <definition>
-                      <sections>
-                        <section name="">
-                          <default-page>
-                            <page size="224,316.8" header-offset="15" footer-offset="15" unit="mm">
-                              <margins left="20" right="20" top="20" bottom="20" />
-                            </page>
-                          </default-page>
-                        </section>
-                      </sections>
-                    </definition>
                     <content>
                       <paragraph>
                         <style numbering-type="None">
@@ -2384,6 +2373,7 @@
                 <style class="Flat Light Green" />
                 <entity pk-constraint-name="PK_WORKSPACE_BILLINGPLAN_ID" description="Deffines current state of billing plan for workspace" />
                 <attributes>
+                  <attribute uid="a1037ef123e2f4e5bba8993964bafcb81218" cid="ELEM231" name="Id" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="false" primary-key="true" nullable="false" description="Primary key of WorkspaceBilling record" default-value="" auto-increment="true" creation-date="08/17/2021 08:01:22" />
                   <attribute uid="a909885cbfed747b798799b779e7fcfab446" cid="ELEM097" name="WorkspaceId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Reference to owning workspace" default-value="" auto-increment="false" creation-date="07/27/2021 08:35:14" />
                   <attribute uid="a99ec607b847d4f78beae62fd8ac95f4d636" cid="ELEM096" name="BillingPlanId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Reference to billing plan" default-value="" auto-increment="false" creation-date="07/27/2021 08:34:05" />
                   <attribute uid="a83e725096a954d0ca3b709613d71a68c446" cid="ELEM098" name="Created" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Timestamp when billing was created" default-value="getdate()" auto-increment="false" creation-date="07/27/2021 08:35:14" />
@@ -2413,17 +2403,6 @@
                       </style>
                     </default>
                     <styles />
-                    <definition>
-                      <sections>
-                        <section name="">
-                          <default-page>
-                            <page size="224,316.8" header-offset="15" footer-offset="15" unit="mm">
-                              <margins left="20" right="20" top="20" bottom="20" />
-                            </page>
-                          </default-page>
-                        </section>
-                      </sections>
-                    </definition>
                     <content>
                       <paragraph>
                         <style numbering-type="None">
@@ -2458,15 +2437,20 @@
                   <stereotype id="4629c8efe5764821a4f2ffb806413d2d_table_c" type="table" ref="" />
                 </stereotype-instances>
                 <style class="Flat Light Green" />
-                <entity pk-constraint-name="PK_METADOCUMENT_BILLING_PLAN_ID" description="Association of metadocument and billing plan" />
+                <entity pk-constraint-name="PK_METADOCUMENTBILLING_ID" description="Association of metadocument and billing plan with properties. Stores information about processed documents (name, status timestamps, etc.) relates to workspace billing plan selection." />
                 <attributes>
-                  <attribute uid="a11608f1f311d4da09f10c0070b88b5f2306" cid="ELEM093" name="MetadocumentId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Reference to owning metadocument" default-value="" auto-increment="false" creation-date="07/27/2021 08:29:14" />
-                  <attribute uid="a2f2c9c5672b7413aba974fc785737ec5306" cid="ELEM094" name="BillingPlanId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Reference to billing plan" default-value="" auto-increment="false" creation-date="07/27/2021 08:29:14" />
+                  <attribute uid="a11608f1f311d4da09f10c0070b88b5f2306" cid="ELEM093" name="MetadocumentId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="true" description="Reference to owning metadocument" default-value="" auto-increment="false" creation-date="07/27/2021 08:29:14" />
+                  <attribute uid="a6c6b7df2556b4563be8776013b3761c7466" cid="ELEM232" name="WorkspaceBillingId" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Reference to workspace billing plan" default-value="" auto-increment="false" creation-date="08/17/2021 08:01:52" />
                   <attribute uid="a231a79cc69c44756aacc257f404b281c276" cid="ELEM125" name="CreditCost" type="int" type-id="MsSql.int" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Numeric value of billing plan spending. Depends on BillingPlan." default-value="0" auto-increment="false" creation-date="07/30/2021 10:28:09" />
                   <attribute uid="a6ce05ddc36634bdf9842d4420fffb834276" cid="ELEM126" name="Watermark" type="bit" type-id="MsSql.bit" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Flag if watermarked" default-value="0" auto-increment="false" creation-date="07/30/2021 10:28:09" />
-                  <attribute uid="a40369693656f47a2a85c1834048a7542276" cid="ELEM127" name="Quality" type="int" type-id="MsSql.int" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Process quality 0 = lowest" default-value="0" auto-increment="false" creation-date="07/30/2021 10:28:09" />
+                  <attribute uid="a40369693656f47a2a85c1834048a7542276" cid="ELEM127" name="Quality" type="int" type-id="MsSql.int" type-size="" foreign-key="true" primary-key="false" nullable="false" description="Process quality 0 = lowest" default-value="0" auto-increment="false" creation-date="07/30/2021 10:28:09" />
                   <attribute uid="ae7e135e729e048f5bca1988ef7120faa276" cid="ELEM128" name="ProcessProfile" type="varchar" type-id="MsSql.varchar" type-size="5" foreign-key="false" primary-key="false" nullable="true" description="Processing profile code" default-value="" auto-increment="false" creation-date="07/30/2021 10:28:09" />
                   <attribute uid="aa39c2b230da148bebd9c7d8a0730cc09277" cid="ELEM129" name="Test" type="bit" type-id="MsSql.bit" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Flag if testing mode" default-value="0" auto-increment="false" creation-date="07/30/2021 10:28:09" />
+                  <attribute uid="a00379a87ac814d2f9734a946ce71b4cb720" cid="ELEM233" name="Procesed" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="true" description="Timestamp when document was processed" default-value="" auto-increment="false" creation-date="08/17/2021 08:09:05" />
+                  <attribute uid="abd820f6735c14bcab09d2bb55ad58aee720" cid="ELEM234" name="ProcessStart" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="true" description="Timestamp when document set to processing state" default-value="" auto-increment="false" creation-date="08/17/2021 08:09:05" />
+                  <attribute uid="a8c3104ed1490424295656c834aad0de6720" cid="ELEM235" name="Downloaded" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="true" description="Timestamp when document was last downloaded" default-value="" auto-increment="false" creation-date="08/17/2021 08:09:05" />
+                  <attribute uid="ad539b668a2934817bba839e98d84e1e0720" cid="ELEM236" name="ProcessState" type="int" type-id="MsSql.int" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Last state of processing (OK,Fail)" default-value="" auto-increment="false" creation-date="08/17/2021 08:09:05" />
+                  <attribute uid="af30e2b6dfae34ddb872071fcf179eb7b721" cid="ELEM237" name="PSInstance" type="varchar" type-id="MsSql.varchar" type-size="100" foreign-key="false" primary-key="false" nullable="true" description="Process server instance identifier" default-value="" auto-increment="false" creation-date="08/17/2021 08:09:05" />
                   <attribute uid="a5dd36ba234fa45179cd10df803b9c3aa821" cid="ELEM100" name="Created" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Timestamp when billing was created" default-value="getdate()" auto-increment="false" creation-date="07/27/2021 08:35:33" />
                   <attribute uid="a3ccab2f5210a4039b5d8c86ab7e4056c821" cid="ELEM101" name="Modified" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="true" description="Timestamp when billing was modified" default-value="" auto-increment="false" creation-date="07/27/2021 08:35:33" />
                 </attributes>
@@ -2498,18 +2482,26 @@
                   </attribute-pairs>
                 </erd-relation>
               </item>
-              <item id="167a4ad792514f09a7ae7527b8d0e7f6" cid="REL034" type="erd-relationship" name="REL_MetadocumentBilling_BillingPlan" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/27/2021 08:37:11" from="4629c8efe5764821a4f2ffb806413d2d" to="f37cd509043e4341b287f015399edb95">
+              <item id="3a5d239825ed496b9e4a88608b4d49ba" cid="ENT019" type="erd-entity" name="Registration" style-class="Flat Light Red" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="08/17/2021 09:26:32">
                 <stereotypes>
-                  <stereotype name="relation" />
+                  <stereotype name="table" />
                 </stereotypes>
                 <stereotype-instances>
-                  <stereotype id="167a4ad792514f09a7ae7527b8d0e7f6_relation_c" type="relation" ref="" />
+                  <stereotype id="3a5d239825ed496b9e4a88608b4d49ba_table_c" type="table" ref="" />
                 </stereotype-instances>
-                <erd-relation type="Identifying" multiplicity-from="1" multiplicity-to="1">
-                  <attribute-pairs>
-                    <attribute-pair from-attribute="a2f2c9c5672b7413aba974fc785737ec5306" to-attribute="acd3b80d7b7ca448b98699942d2ca060a959" />
-                  </attribute-pairs>
-                </erd-relation>
+                <style class="Flat Light Red" />
+                <entity pk-constraint-name="OK_REGISTRATION_ID" description="Holds Process Server registrations" />
+                <attributes>
+                  <attribute uid="a1767a774d3ed49f7bf7f6b697d958d9c422" cid="ELEM238" name="Id" type="bigint" type-id="MsSql.bigint" type-size="" foreign-key="false" primary-key="true" nullable="false" description="Primary key of Registration record" default-value="" auto-increment="true" creation-date="08/17/2021 09:27:33" />
+                  <attribute uid="afb4231a7494547d781d070ff32800205191" cid="ELEM241" name="PSInstance" type="varchar" type-id="MsSql.varchar" type-size="100" foreign-key="false" primary-key="false" nullable="true" description="Process server instance identifier" default-value="" auto-increment="false" creation-date="08/17/2021 09:30:33" />
+                  <attribute uid="a2428945f5b7f4db8be24fcfc69e0a2d9529" cid="ELEM245" name="LocationIP" type="varchar" type-id="MsSql.varchar" type-size="100" foreign-key="false" primary-key="false" nullable="true" description="Process server instance identifier" default-value="" auto-increment="false" creation-date="08/17/2021 09:47:08" />
+                  <attribute uid="a43ee7873d3ad4cb0ab9dd2d18082ee72109" cid="ELEM242" name="LastActivity" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="true" description="Timestamp latest activity" default-value="" auto-increment="false" creation-date="08/17/2021 09:30:33" />
+                  <attribute uid="a561e1497aa4b46468e856418d9c2c20a879" cid="ELEM243" name="DocumentProcessedCnt" type="int" type-id="MsSql.int" type-size="" foreign-key="false" primary-key="false" nullable="false" description="# of new processed documents" default-value="" auto-increment="false" creation-date="08/17/2021 09:32:33" />
+                  <attribute uid="a16ba37593de641e0a1b3ed0644c19bd9880" cid="ELEM244" name="DocumentFailedCnt" type="int" type-id="MsSql.int" type-size="" foreign-key="false" primary-key="false" nullable="false" description="# of failed documents" default-value="" auto-increment="false" creation-date="08/17/2021 09:32:33" />
+                  <attribute uid="a97df38f69fa64de69836de68cdb56644854" cid="ELEM239" name="Created" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="false" description="Timestamp when registration was created" default-value="getdate()" auto-increment="false" creation-date="08/17/2021 09:29:03" />
+                  <attribute uid="ac2b860bd93804dee84ca79c6bfb54a4a854" cid="ELEM240" name="Modified" type="datetime" type-id="MsSql.datetime" type-size="" foreign-key="false" primary-key="false" nullable="true" description="Timestamp when registration was modified" default-value="" auto-increment="false" creation-date="08/17/2021 09:29:03" />
+                </attributes>
+                <indexes />
               </item>
               <item id="559c3bab33704212a52e594be57174e9" cid="REL035" type="erd-relationship" name="REL_WorkspaceBilling_BillingPlan" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/27/2021 08:37:45" from="e80985e7fce14193b34889876668ff81" to="f37cd509043e4341b287f015399edb95">
                 <stereotypes>
@@ -2860,6 +2852,19 @@
                   </index>
                 </indexes>
               </item>
+              <item id="973eb5eddaff48c3bbd017504a6a6bec" cid="REL065" type="erd-relationship" name="REL_MetadocumentBilling_WorkspaceBilling" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="08/17/2021 08:11:09" from="4629c8efe5764821a4f2ffb806413d2d" to="e80985e7fce14193b34889876668ff81">
+                <stereotypes>
+                  <stereotype name="relation" />
+                </stereotypes>
+                <stereotype-instances>
+                  <stereotype id="973eb5eddaff48c3bbd017504a6a6bec_relation_c" type="relation" ref="" />
+                </stereotype-instances>
+                <erd-relation type="Identifying" multiplicity-from="1" multiplicity-to="1">
+                  <attribute-pairs>
+                    <attribute-pair from-attribute="a6c6b7df2556b4563be8776013b3761c7466" to-attribute="a1037ef123e2f4e5bba8993964bafcb81218" />
+                  </attribute-pairs>
+                </erd-relation>
+              </item>
             </abstract-items>
             <layer id="6fa09190adbe4d97861d913962fcbf64" name="Default" visible="true" enabled="true" locked="false">
               <item id="ef322c9446f34d3db88bcf4cbdcbbbda" iid="68002f8afdb045bea4ad4abf68c5d193" creation-date="07/26/2021 15:46:45" order-index="0" type="entity">
@@ -2951,25 +2956,25 @@
                 <relation from="24a5c2e6d7df4dd380da583904b6e81c" from-iid="79f5dcb934c842a1bddc246988b2b33b" from-field="a496263d90bf347b99c6ee14a5044ee26898" to="ffff693c63d845f9b0e790d6a21b9e82" to-iid="d3884eea96d146279273a0380a41471b" to-field="a30fbe5330e3e4ee3a90358bf418197bc703" />
               </item>
               <item id="80e14dbf9d8f4a9f9e52efcb92fe8e97" iid="227931401c474ce3953e7ec02287e8a4" creation-date="07/27/2021 06:05:06" order-index="12" type="entity">
-                <layout ax="2409" ay="565" awidth="326" aheight="303" x="2409" y="565" width="326" height="303" rotation-center="-93,-8.5" />
+                <layout ax="2600" ay="537" awidth="326" aheight="303" x="2600" y="537" width="326" height="303" rotation-center="-93,-8.5" />
                 <erd-entity show-nullability="true" show-description="true" />
               </item>
               <item id="e2e6ca43a64545698cedbf9cceb58a46" iid="277446c0927c46fcaa7f0a46fa8e62f4" creation-date="07/27/2021 07:02:26" order-index="13" type="relation">
-                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-start-point="true" lock-to-fields="true" auto-path="" x1="2409" y1="707" x2="2313" y2="580" start-border-pos="0.883250825082508" end-border-pos="0.304819915254237" start-local-pos="142" end-local-pos="104" name-position="0,20">
+                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-start-point="true" lock-to-fields="true" auto-path="" x1="2600" y1="679" x2="2313" y2="580" start-border-pos="0.883250825082508" end-border-pos="0.304819915254237" start-local-pos="142" end-local-pos="104" name-position="0,20">
                   <points>
-                    <point x="2409" y="707" />
+                    <point x="2600" y="679" />
                     <point x="2313" y="580" />
                   </points>
                 </layout>
                 <relation from="80e14dbf9d8f4a9f9e52efcb92fe8e97" from-iid="227931401c474ce3953e7ec02287e8a4" from-field="ae420ab80ac584385b1426d0202fef72114" to="24a5c2e6d7df4dd380da583904b6e81c" to-iid="79f5dcb934c842a1bddc246988b2b33b" to-field="a7dde6800c37940389459c8caf8b01322535" />
               </item>
               <item id="d89142916c59480eb82462bf6adff7d8" iid="8a9b142cb3d54eb3a29bbc4179892c7d" creation-date="07/27/2021 07:03:03" order-index="14" type="relation">
-                <layout start-role-position="25,15" end-role-position="25,-15" line-style="oblique" lock-start-point="true" lock-end-point="true" lock-to-fields="true" auto-path="" x1="2409" y1="668" x2="2409" y2="726" start-border-pos="0.91460396039604" end-border-pos="0.867574257425743" start-local-pos="103" end-local-pos="161" name-position="0,20">
+                <layout start-role-position="25,15" end-role-position="25.9998,-14.98698" line-style="oblique" lock-start-point="true" lock-end-point="true" lock-to-fields="true" auto-path="" x1="2600" y1="640" x2="2600" y2="698" start-border-pos="0.91460396039604" end-border-pos="0.867574257425743" start-local-pos="103" end-local-pos="161" name-position="0,20">
                   <points>
-                    <point x="2409" y="668" />
-                    <point x="2208" y="727.5" />
-                    <point x="2206" y="670" />
-                    <point x="2409" y="726" />
+                    <point x="2600" y="640" />
+                    <point x="2524" y="638" />
+                    <point x="2523" y="699" />
+                    <point x="2600" y="698" />
                   </points>
                 </layout>
                 <relation from="80e14dbf9d8f4a9f9e52efcb92fe8e97" from-iid="227931401c474ce3953e7ec02287e8a4" from-field="af143d15824124110b676deab330b5bfd973" to="80e14dbf9d8f4a9f9e52efcb92fe8e97" to-iid="227931401c474ce3953e7ec02287e8a4" to-field="ad209340532f94e32b4cf1917e5a20cd6364" />
@@ -3009,10 +3014,10 @@
                 <relation from="b67864ae142447b087be3d82e8f18e70" from-iid="4f2ffee5135f42ba8190dd0911d849e9" from-field="a2da35409cd704d75b9a8472accca9a93740" to="ef322c9446f34d3db88bcf4cbdcbbbda" to-iid="68002f8afdb045bea4ad4abf68c5d193" to-field="a807a3f93ff154a9bbd2f13a3b9971b2c353" />
               </item>
               <item id="c0ce9ad877694d26bc57b50f21db5a58" iid="9362b9135d9a4f22a87420b2a82ae008" creation-date="07/27/2021 07:56:09" order-index="21" type="relation">
-                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-start-point="true" lock-to-fields="true" auto-path="" x1="2600" y1="1760" x2="2735" y2="668" start-border-pos="0.904296875" end-border-pos="0.33539603960396" start-local-pos="122" end-local-pos="103" name-position="0,20">
+                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-start-point="true" lock-to-fields="true" auto-path="" x1="2600" y1="1760" x2="2600" y2="640" start-border-pos="0.904296875" end-border-pos="0.91460396039604" start-local-pos="122" end-local-pos="103" name-position="0,20">
                   <points>
                     <point x="2600" y="1760" />
-                    <point x="2735" y="668" />
+                    <point x="2600" y="640" />
                   </points>
                 </layout>
                 <relation from="f19722e950a347d9946336728e7a9b9c" from-iid="779a4cd4f1d1476ea87da5d9a66f8c12" from-field="a1f51f395d6344cc4a44d1de584a84ee0454" to="80e14dbf9d8f4a9f9e52efcb92fe8e97" to-iid="227931401c474ce3953e7ec02287e8a4" to-field="af143d15824124110b676deab330b5bfd973" />
@@ -3165,51 +3170,42 @@
                 <relation from="f37cd509043e4341b287f015399edb95" from-iid="0b76e177c91146009ba75aebd5a5517c" from-field="af234efad39804df2888a5629fdc290d9959" to="ef322c9446f34d3db88bcf4cbdcbbbda" to-iid="68002f8afdb045bea4ad4abf68c5d193" to-field="a807a3f93ff154a9bbd2f13a3b9971b2c353" />
               </item>
               <item id="4629c8efe5764821a4f2ffb806413d2d" iid="a8224407a4be49b9a96cdea96c056054" creation-date="07/27/2021 08:26:11" order-index="41" type="entity">
-                <layout ax="970" ay="1546" awidth="403" aheight="289" x="970" y="1546" width="403" height="289" rotation-center="-131.5,-64" />
+                <layout ax="1341.5" ay="1517" awidth="403" aheight="398" x="1341.5" y="1517" width="403" height="289" rotation-center="-131.5,-64" />
                 <erd-entity show-nullability="true" show-description="true" />
               </item>
               <item id="e80985e7fce14193b34889876668ff81" iid="aed881e5e9074359a10bd1cac19d9d0e" creation-date="07/27/2021 08:32:24" order-index="42" type="entity">
-                <layout ax="970" ay="1276" awidth="302" aheight="255" x="970" y="1276" width="302" height="255" rotation-center="-81,3" />
+                <layout ax="944" ay="1299" awidth="302" aheight="448" x="944" y="1299" width="302" height="448" rotation-center="-81,-51.5" />
                 <erd-entity show-nullability="true" show-description="true" />
               </item>
               <item id="6b0f4effcc524aaa89b6ea063ce02c78" iid="9fabc9f3a31e41c3a1efa275bcf8c796" creation-date="07/27/2021 08:35:48" order-index="43" type="relation">
-                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-to-fields="true" auto-path="" x1="1272" y1="1380" x2="1884" y2="579" start-border-pos="0.351470588235294" end-border-pos="0.945180084745763" start-local-pos="104" end-local-pos="103" name-position="0,20">
+                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-to-fields="true" auto-path="" x1="1246" y1="1422" x2="1884" y2="579" start-border-pos="0.318359375" end-border-pos="0.945180084745763" start-local-pos="123" end-local-pos="103" name-position="0,20">
                   <points>
-                    <point x="1272" y="1380" />
+                    <point x="1246" y="1422" />
                     <point x="1884" y="579" />
                   </points>
                 </layout>
                 <relation from="e80985e7fce14193b34889876668ff81" from-iid="aed881e5e9074359a10bd1cac19d9d0e" from-field="a909885cbfed747b798799b779e7fcfab446" to="24a5c2e6d7df4dd380da583904b6e81c" to-iid="79f5dcb934c842a1bddc246988b2b33b" to-field="a7dde6800c37940389459c8caf8b01322535" />
               </item>
               <item id="01ce4003e9ff46e890652dffa23fe01b" iid="6a21714cd4d74d6a8a44368ec3ef7a96" creation-date="07/27/2021 08:36:33" order-index="44" type="relation">
-                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-to-fields="true" auto-path="" x1="1373" y1="1632" x2="2600" y2="1742" start-border-pos="0.324826989619377" end-border-pos="0.919140625" start-local-pos="86" end-local-pos="104" name-position="0,20">
+                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-to-fields="true" auto-path="" x1="1744" y1="1638" x2="2600" y2="1742" start-border-pos="0.325690954773869" end-border-pos="0.919140625" start-local-pos="121" end-local-pos="104" name-position="0,20">
                   <points>
-                    <point x="1373" y="1632" />
+                    <point x="1744" y="1638" />
                     <point x="2600" y="1742" />
                   </points>
                 </layout>
                 <relation from="4629c8efe5764821a4f2ffb806413d2d" from-iid="a8224407a4be49b9a96cdea96c056054" from-field="a11608f1f311d4da09f10c0070b88b5f2306" to="f19722e950a347d9946336728e7a9b9c" to-iid="779a4cd4f1d1476ea87da5d9a66f8c12" to-field="a7b64ac4b5cba4a7e9b2cb89ee667f597861" />
               </item>
-              <item id="167a4ad792514f09a7ae7527b8d0e7f6" iid="2b905595bd564a4d83a81604e4aa9664" creation-date="07/27/2021 08:37:11" order-index="45" type="relation">
-                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-to-fields="true" auto-path="" x1="970" y1="1652" x2="1272" y2="2018" start-border-pos="0.908737024221453" end-border-pos="0.304819915254237" start-local-pos="106" end-local-pos="103" name-position="0,20">
-                  <points>
-                    <point x="970" y="1652" />
-                    <point x="1272" y="2018" />
-                  </points>
-                </layout>
-                <relation from="4629c8efe5764821a4f2ffb806413d2d" from-iid="a8224407a4be49b9a96cdea96c056054" from-field="a2f2c9c5672b7413aba974fc785737ec5306" to="f37cd509043e4341b287f015399edb95" to-iid="0b76e177c91146009ba75aebd5a5517c" to-field="acd3b80d7b7ca448b98699942d2ca060a959" />
-              </item>
               <item id="559c3bab33704212a52e594be57174e9" iid="83cdd40be1a34a8cb05c7c64b6720ff2" creation-date="07/27/2021 08:37:45" order-index="46" type="relation">
-                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-to-fields="true" auto-path="" x1="970" y1="1398" x2="1272" y2="2018" start-border-pos="0.879901960784314" end-border-pos="0.304819915254237" start-local-pos="122" end-local-pos="103" name-position="0,20">
+                <layout start-role-position="25,15" end-role-position="25,-15" line-style="straight" lock-to-fields="true" auto-path="" x1="944" y1="1440" x2="1272" y2="2018" start-border-pos="0.921037946428571" end-border-pos="0.304819915254237" start-local-pos="141" end-local-pos="103" name-position="0,20">
                   <points>
-                    <point x="970" y="1398" />
+                    <point x="944" y="1440" />
                     <point x="1272" y="2018" />
                   </points>
                 </layout>
                 <relation from="e80985e7fce14193b34889876668ff81" from-iid="aed881e5e9074359a10bd1cac19d9d0e" from-field="a99ec607b847d4f78beae62fd8ac95f4d636" to="f37cd509043e4341b287f015399edb95" to-iid="0b76e177c91146009ba75aebd5a5517c" to-field="acd3b80d7b7ca448b98699942d2ca060a959" />
               </item>
               <item id="di695f5776397544efaecb3f3c01c329ca5845" iid="43c4e7069183458cbcca98a0aa160a0d" name="" creation-date="07/27/2021 08:48:41" order-index="47" type="diagram-description">
-                <layout ax="1023" ay="213" awidth="350" aheight="180" x="1023" y="213" width="350" height="180" />
+                <layout ax="523.5" ay="11" awidth="350" aheight="180" x="523.5" y="11" width="350" height="180" />
               </item>
               <item id="9780151cdc1c40fbb9227d75cac4e47f" iid="e1b5eaa7341c435daba5b4b05028b878" creation-date="07/30/2021 18:43:54" order-index="48" type="entity">
                 <layout ax="1495" ay="-288" awidth="389" aheight="536" x="1495" y="-288" width="389" height="504" rotation-center="127.5,8" />
@@ -3317,6 +3313,19 @@
                 <layout ax="1050" ay="-326" awidth="322" aheight="517" x="1050" y="-326" width="322" height="515" rotation-center="-94,-37.5" />
                 <erd-entity show-nullability="true" show-description="true" />
               </item>
+              <item id="973eb5eddaff48c3bbd017504a6a6bec" iid="9092e22f38484607ba02f8c1667136d4" creation-date="08/17/2021 08:11:09" order-index="63" type="relation">
+                <layout start-role-position="25,15" end-role-position="25,-15" line-style="oblique" lock-to-fields="true" auto-path="" x1="1342" y1="1629" x2="1246" y2="1402" start-border-pos="0.929662273157781" end-border-pos="0.307756696428571" end-local-pos="103" name-position="0,20">
+                  <points>
+                    <point x="1342" y="1629" />
+                    <point x="1246" y="1402" />
+                  </points>
+                </layout>
+                <relation from="4629c8efe5764821a4f2ffb806413d2d" from-iid="a8224407a4be49b9a96cdea96c056054" to="e80985e7fce14193b34889876668ff81" to-iid="aed881e5e9074359a10bd1cac19d9d0e" to-field="a1037ef123e2f4e5bba8993964bafcb81218" />
+              </item>
+              <item id="3a5d239825ed496b9e4a88608b4d49ba" iid="f83b50caf747406bac8a3fd15e53d170" creation-date="08/17/2021 09:26:32" order-index="64" type="entity">
+                <layout ax="713" ay="-320" awidth="264" aheight="247" x="713" y="-320" width="264" height="247" rotation-center="0,107.5" />
+                <erd-entity show-nullability="true" show-description="true" />
+              </item>
             </layer>
           </diagram>
         </model>
@@ -4325,16 +4334,16 @@
                       <item id="9a662f3ae65b496193f8b84bd1da19ea" cid="GRD009" type="ui-grid" name="Grid8" style-class="" owner="407791e64a7544d3bf9ae397d6ce22f1" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/28/2021 07:32:18">
                         <grid>
                           <columns>
-                            <column id="uigc-45ca3aaf-bff9-443e-87a0-df8c8c80af82" name="Date" />
-                            <column id="uigc-cdfe7866-760e-48b7-b700-65b335095f1f" name="Ivoice Number" />
-                            <column id="uigc-9f77fb23-8d61-405f-b7f6-70f8d963a791" name="Items" />
-                            <column id="uigc-a3d4ed02-9b6f-42b6-ad04-55c9863d3f55" name="Billing Plan" />
-                            <column id="uigc-acca6fd5-8645-42a3-a094-8b28fd56a8aa" name="Billing Info" />
-                            <column id="uigc-e64bf533-0fd4-42d0-b15e-95c6b986d436" name="Total incl VAT" />
-                            <column id="uigc-298b9c0c-e1f9-42db-a0bf-3cdb238fd9fb" name="Total Base" />
-                            <column id="uigc-ff9d74a0-d345-428d-ad3c-71c5997d011d" name="VAT" />
-                            <column id="uigc-f3000578-7926-4201-a054-393b8da86c9d" name="Payed" />
-                            <column id="uigc-54cdec40-f65f-405b-9c75-4607c5ead84b" name="Channel" />
+                            <column id="uigc-ff6d9000-3b17-420c-820e-b096415de505" name="Date" />
+                            <column id="uigc-686b4cbb-4191-4247-a885-203e1e0c3e7d" name="Ivoice Number" />
+                            <column id="uigc-ef0c8cef-8654-4efb-91a5-246e6c4c81e1" name="Items" />
+                            <column id="uigc-f581a598-1e3f-48bd-a6ca-fa1f502ef499" name="Billing Plan" />
+                            <column id="uigc-0903c79d-3695-475f-8765-3f62c9c3a7c0" name="Billing Info" />
+                            <column id="uigc-46d01587-589e-42cb-a657-8f61e4c2a4df" name="Total incl VAT" />
+                            <column id="uigc-b73d12c7-e896-4b3b-8e5c-7a05438dc888" name="Total Base" />
+                            <column id="uigc-0454ea0c-2c96-4096-aa9a-9bf917ac243e" name="VAT" />
+                            <column id="uigc-29394bee-df26-4918-b415-122fd5b1fbb1" name="Payed" />
+                            <column id="uigc-536031b2-14ba-42cd-8ba0-626568c83749" name="Channel" />
                           </columns>
                         </grid>
                       </item>
@@ -4356,11 +4365,11 @@
                       <item id="1cbba24993da466f907d82542e588b8d" cid="GRD010" type="ui-grid" name="Grid9" style-class="" owner="97fe3aeca36542caa316f33eaa756f6a" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/28/2021 07:35:56">
                         <grid>
                           <columns>
-                            <column id="uigc-6c525d55-b020-4c05-b024-be454ebb3dd6" name="Date" />
-                            <column id="uigc-1dad96c2-b8fa-4a02-b622-1845882c7806" name="Name" />
-                            <column id="uigc-ac693dc1-4312-4be1-a4f8-6d24446e1f18" name="QTY" />
-                            <column id="uigc-c786cb8b-7834-4ace-b557-c1f208ed6957" name="SubTotal base" />
-                            <column id="uigc-554e2e95-137e-4045-8be7-5d851b27ad72" name="SubTotal VAT" />
+                            <column id="uigc-0c580bd6-2144-4e6f-8e6a-3638f9a8e182" name="Date" />
+                            <column id="uigc-54d801f6-4b1e-41f1-b6de-86ed456fd489" name="Name" />
+                            <column id="uigc-78e6a99e-3e40-4b34-893f-5317685e1e0d" name="QTY" />
+                            <column id="uigc-962b9e40-8e7b-4a26-b040-5de115d9e148" name="SubTotal base" />
+                            <column id="uigc-5f7b8745-2b10-4cb5-9dbc-cbb8a43e50a9" name="SubTotal VAT" />
                           </columns>
                         </grid>
                       </item>
@@ -4469,14 +4478,14 @@
                         </stereotype-instances>
                         <grid>
                           <columns>
-                            <column id="uigc-a0850619-a00d-4077-9f2e-d04cae28e537" name="Status" />
-                            <column id="uigc-692ae3f3-48c3-4775-bfa0-312f45800618" name="Name" />
-                            <column id="uigc-21eb811c-4edc-4737-865b-5e660a3ce02a" name="Location" />
-                            <column id="uigc-aa52f0d1-2bc3-4e9b-bfd6-c82822ccbdeb" name="Tags" />
-                            <column id="uigc-6913f915-5451-4352-b673-fbafb7674c36" name="Uploaded" />
-                            <column id="uigc-28f0282d-ec53-4b0f-95b3-08a0ff55a00b" name="Uploader" />
-                            <column id="uigc-cd626ee8-4bc0-44db-b731-750e1bb6b17a" name="Processed" />
-                            <column id="uigc-41c56cad-cf01-4fd4-8bef-f23e88881511" name="Downloaded" />
+                            <column id="uigc-ec594a99-f2df-4805-8759-6f2c3fb73bcc" name="Status" />
+                            <column id="uigc-6b8970e4-9caf-41d0-b1ac-6a41bc8ce4b0" name="Name" />
+                            <column id="uigc-63edee56-f112-49dd-ac82-03ef1df40183" name="Location" />
+                            <column id="uigc-1fdfecfe-713a-4fde-ae84-bf6028e9d379" name="Tags" />
+                            <column id="uigc-2dca269c-63bd-4583-962b-bc78ddbb2c5c" name="Uploaded" />
+                            <column id="uigc-5f97ad32-3066-469d-bb20-57b7b8fac498" name="Uploader" />
+                            <column id="uigc-54f4f227-950c-49a5-80a8-fe3e7701b6c4" name="Processed" />
+                            <column id="uigc-0e15d62d-8457-4da3-b4ca-be0dabc8bcd5" name="Downloaded" />
                           </columns>
                         </grid>
                       </item>
@@ -4498,8 +4507,8 @@
                       <item id="aba3e589e4ec46e6a26e6cdb4c4e5a7a" cid="GRD005" type="ui-grid" name="Grid5" style-class="" owner="6ece78a4080f4a83867efba2d70b4de5" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/28/2021 07:04:44">
                         <grid>
                           <columns>
-                            <column id="uigc-92eeeb05-481d-49a8-a3f8-35cba26cf3c0" name="Name" />
-                            <column id="uigc-e6d0563d-5ed7-4d7f-963e-d079d6aa5766" name="Size" />
+                            <column id="uigc-24686ca5-6a86-42bb-8286-df6956bd1902" name="Name" />
+                            <column id="uigc-7893ca59-769e-404e-9baa-80249e4c1829" name="Size" />
                           </columns>
                         </grid>
                       </item>
@@ -4508,10 +4517,10 @@
                       <item id="903705b4cf244c66861cfabd5185f41d" cid="GRD006" type="ui-grid" name="Grid6" style-class="" owner="6ece78a4080f4a83867efba2d70b4de5" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/28/2021 07:07:24">
                         <grid>
                           <columns>
-                            <column id="uigc-2ce0a58a-1f03-4380-8ea9-45339d3c3872" name="Date" />
-                            <column id="uigc-472e21fc-4d84-40b3-9bd7-f4c1b491794d" name="Status" />
-                            <column id="uigc-a4b40427-365d-4a19-955f-1da6cd28533e" name="User" />
-                            <column id="uigc-34ce4fee-8d41-4beb-9d73-8f7fe36a2ac0" name="Message" />
+                            <column id="uigc-455a9da0-f52f-4e64-99e8-fffd62fc83e1" name="Date" />
+                            <column id="uigc-5edbb5fd-ea9b-4c6f-a713-08c5103b624e" name="Status" />
+                            <column id="uigc-e0e76d80-3c8f-4636-b8f9-39df2c933554" name="User" />
+                            <column id="uigc-7b1825ed-3c9c-4bac-9309-37fc358aae74" name="Message" />
                           </columns>
                         </grid>
                       </item>
@@ -5196,8 +5205,8 @@
                   </item>
                   <item id="1085a5f86a0944c0ad687f6e06cffb50" cid="REL015" type="relationship" name="" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/30/2021 12:12:09" from="dc62b4a6eddb4ffea9922a1210e1965a" to="13a6b5d699e34724b34d2f0e3cf411f6" visibility="package">
                     <relation from="dc62b4a6eddb4ffea9922a1210e1965a" to="13a6b5d699e34724b34d2f0e3cf411f6" derived="false">
-                      <start-role id="umlar-75438802-2e01-4eaf-a607-709e2f869558" name="" multiplicity="1" navigability="yes" association-type="association" visibility="public" />
-                      <end-role id="umlar-47ced68c-0a87-498a-8686-753525dfa874" name="" multiplicity="1" navigability="yes" association-type="association" visibility="private" />
+                      <start-role id="umlar-bff59b8e-c398-4291-a6c9-c4d554fb963e" name="" multiplicity="1" navigability="yes" association-type="association" visibility="public" />
+                      <end-role id="umlar-136d5bea-f405-45dd-a63a-ba4f1f501cf8" name="" multiplicity="1" navigability="yes" association-type="association" visibility="private" />
                     </relation>
                   </item>
                   <item id="d197a10d487f4feca76eaaa52539564d" cid="C015" type="class" name="Metadocument" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/30/2021 12:13:29" visibility="undefined">
@@ -5218,6 +5227,9 @@
                       <owned-item ref="4ec933cf2fc84617a9a8494196004a90" />
                       <owned-item ref="4ec933cf2fc84617a9a8494196004a90" />
                       <owned-item ref="4ec933cf2fc84617a9a8494196004a90" />
+                      <owned-item ref="4ec933cf2fc84617a9a8494196004a90" />
+                      <owned-item ref="4ec933cf2fc84617a9a8494196004a90" />
+                      <owned-item ref="4ec933cf2fc84617a9a8494196004a90" />
                     </owned-items>
                     <attributes>
                       <attribute id="a41e119653aca4d98832721d5cffe17c3247" cid="PROP008" name="Created" creation-date="07/30/2021 13:08:53" property-ref="4ec933cf2fc84617a9a8494196004a90" />
@@ -5313,6 +5325,12 @@
                       <owned-item ref="5ed1b0ad3800445a852c688e71a6c3de" />
                       <owned-item ref="f329c375b119435e8347637cc1bace4f" />
                       <owned-item ref="5ed1b0ad3800445a852c688e71a6c3de" />
+                      <owned-item ref="f329c375b119435e8347637cc1bace4f" />
+                      <owned-item ref="5ed1b0ad3800445a852c688e71a6c3de" />
+                      <owned-item ref="f329c375b119435e8347637cc1bace4f" />
+                      <owned-item ref="5ed1b0ad3800445a852c688e71a6c3de" />
+                      <owned-item ref="f329c375b119435e8347637cc1bace4f" />
+                      <owned-item ref="5ed1b0ad3800445a852c688e71a6c3de" />
                     </owned-items>
                     <attributes>
                       <attribute id="ac3f9a2f9163c4d189a8531933c4505ab534" cid="PROP003" name="BillingPlanCopy" creation-date="07/30/2021 13:03:05" property-ref="f329c375b119435e8347637cc1bace4f" />
@@ -5350,8 +5368,8 @@
                   </item>
                   <item id="45a4d933848d4de3b8cfb3de6264f86a" cid="REL023" type="relationship" name="Status" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/30/2021 12:28:30" from="d9b508c513144e22a67092ae79418750" to="d197a10d487f4feca76eaaa52539564d" visibility="package">
                     <relation from="d9b508c513144e22a67092ae79418750" to="d197a10d487f4feca76eaaa52539564d" derived="false">
-                      <start-role id="umlar-8f28637d-46c7-4c68-978d-c1ccedf1a029" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
-                      <end-role id="umlar-2b7043e5-d648-4fbc-9fab-6e5e7101a4fe" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <start-role id="umlar-bd3cadfd-9cc7-4af8-ab6b-eb97a3728e0e" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <end-role id="umlar-ef2eb03f-70c5-4942-a1e4-0a2e4422f790" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
                     </relation>
                   </item>
                   <item id="270ad5efb5d64112afacbeca5ffeca86" cid="C019" type="class" name="BillingPlan" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/30/2021 12:32:46" visibility="undefined">
@@ -5381,6 +5399,12 @@
                       <owned-item ref="2a23d5a19cd848a8b3a41e2d3f2ee886" />
                       <owned-item ref="2950a0ddb8b0416da9ccee2fbe9bf227" />
                       <owned-item ref="2a23d5a19cd848a8b3a41e2d3f2ee886" />
+                      <owned-item ref="2950a0ddb8b0416da9ccee2fbe9bf227" />
+                      <owned-item ref="2a23d5a19cd848a8b3a41e2d3f2ee886" />
+                      <owned-item ref="2950a0ddb8b0416da9ccee2fbe9bf227" />
+                      <owned-item ref="2a23d5a19cd848a8b3a41e2d3f2ee886" />
+                      <owned-item ref="2950a0ddb8b0416da9ccee2fbe9bf227" />
+                      <owned-item ref="2a23d5a19cd848a8b3a41e2d3f2ee886" />
                     </owned-items>
                     <attributes>
                       <attribute id="a9e9ff08df85849a28cc714ae4ca92c24350" cid="PROP005" name="Presets" creation-date="07/30/2021 13:05:16" property-ref="2950a0ddb8b0416da9ccee2fbe9bf227" />
@@ -5399,8 +5423,8 @@
                       <stereotype id="ca3eacde14404b8a939edc0ba600df9b_state_c" type="state" ref="" />
                     </stereotype-instances>
                     <relation from="13a6b5d699e34724b34d2f0e3cf411f6" to="270ad5efb5d64112afacbeca5ffeca86" derived="false">
-                      <start-role id="umlar-4110c721-fe98-4c33-98ef-c12346612966" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
-                      <end-role id="umlar-f2af6107-9824-4c3a-bf01-14e20c83939d" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <start-role id="umlar-23d6d93b-9cf2-4fdf-a809-0cfe19e90083" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <end-role id="umlar-84166289-91d8-40c8-8aa6-06a34115bdfd" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
                     </relation>
                   </item>
                   <item id="39db4851d2f34131ba16e6788ed23770" cid="REL037" type="relationship" name="Consumtion" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/30/2021 12:35:08" from="d197a10d487f4feca76eaaa52539564d" to="270ad5efb5d64112afacbeca5ffeca86" visibility="package">
@@ -5411,14 +5435,14 @@
                       <stereotype id="39db4851d2f34131ba16e6788ed23770_consuption_c" type="consuption" ref="" />
                     </stereotype-instances>
                     <relation from="d197a10d487f4feca76eaaa52539564d" to="270ad5efb5d64112afacbeca5ffeca86" derived="false">
-                      <start-role id="umlar-7b11633a-bfb2-439a-9c63-1fc2f3305431" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
-                      <end-role id="umlar-f803f2e3-085b-47fc-940a-4ec2b03aa335" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <start-role id="umlar-1d34798c-a09d-40cf-bf58-6d5bedd9739a" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <end-role id="umlar-727715a3-ecef-4fa7-85c6-5effbd125eac" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
                     </relation>
                   </item>
                   <item id="b67adb8f034c4b75a300bd2f45ac7be9" cid="REL040" type="relationship" name="CurrentBillingPlan" style-class="" change-tracking-state="added" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/30/2021 12:59:55" from="4603ec6ea7b8400d81d3a658cd91d7b2" to="270ad5efb5d64112afacbeca5ffeca86" visibility="package">
                     <relation from="4603ec6ea7b8400d81d3a658cd91d7b2" to="270ad5efb5d64112afacbeca5ffeca86" derived="false">
-                      <start-role id="umlar-c788fed1-45e1-4e60-b6c0-f59e97ecd698" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
-                      <end-role id="umlar-f9b753cc-02e1-408b-839c-37c622f0150f" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <start-role id="umlar-ef44e1b1-344d-4123-b5eb-5fde54d110f0" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
+                      <end-role id="umlar-f2ab59f2-0da8-45c4-b8f3-47dca796573e" name="" multiplicity="1" navigability="" association-type="association" visibility="public" />
                     </relation>
                   </item>
                   <item id="678131d8520145c6997158360e81dc10" cid="PROP001" type="property" name="IsGold" style-class="" owner="13a6b5d699e34724b34d2f0e3cf411f6" creator="CDoZfQE0eoPT0twKUywpA2Pd3T+96zsw7WLZGMEzIl1z2XhR" creation-date="07/30/2021 13:01:17" visibility="private">

+ 14 - 1
AppServer/Business/Services/Base/UserContextService.cs

@@ -1,8 +1,10 @@
 using System;
 using System.Security.Principal;
 using BO.AppServer.Data.Entity;
+using BO.AppServer.Metadata.Enums;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
 using Quadarax.Foundation.Core.Business;
 
 namespace BO.AppServer.Business.Services.Base
@@ -11,11 +13,15 @@ namespace BO.AppServer.Business.Services.Base
     {
         protected UserManager<IdentityUser> _manUser;
         protected UserRepo _repoUser;
-        protected UserContextService(UserRepo repoUser, UserManager<IdentityUser> userManager, IPrincipal currentPrincipal, ILoggerFactory logger) : base(currentPrincipal, logger)
+        protected Configuration.Configuration _configuration;
+
+        protected UserContextService(IOptions<Configuration.Configuration> config, UserRepo repoUser, UserManager<IdentityUser> userManager, IPrincipal currentPrincipal, ILoggerFactory logger) : base(MaySetDefaultPrincipal(currentPrincipal, config), logger)
         {
             _manUser = userManager ?? throw new ArgumentNullException(nameof(userManager));
             _repoUser = repoUser ?? throw new ArgumentNullException(nameof(repoUser));
+            _configuration = config?.Value ?? throw new ArgumentNullException(nameof(config));
         }
+        
 
         protected User GetCurrentUser()
         {
@@ -27,5 +33,12 @@ namespace BO.AppServer.Business.Services.Base
             var user = GetCurrentUser();
             return user.Id;
         }
+
+        private static IPrincipal MaySetDefaultPrincipal(IPrincipal principal, IOptions<Configuration.Configuration> config)
+        {
+            if (principal?.Identity == null || principal.Identity.Name == "genericIdentity")
+                principal = new GenericPrincipal(new GenericIdentity(config.Value.System.AccountSystem.Name),new[] { RoleEnum.System.ToString() });
+            return principal;
+        }
     }
 }

+ 13 - 7
AppServer/Business/Services/CatalogueService.cs

@@ -11,6 +11,7 @@ using BO.AppServer.Metadata.Dto;
 using BO.AppServer.Metadata.Enums;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
 using Quadarax.Foundation.Core.Data;
 using Quadarax.Foundation.Core.Data.Interface;
 using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
@@ -34,7 +35,8 @@ namespace BO.AppServer.Business.Services
             BillingPlanRepo repoBillingPlan,
             UserRepo repoUser, 
             UserManager<IdentityUser> userManager, 
-            IPrincipal currentPrincipal, ILoggerFactory logger) : base(repoUser, userManager, currentPrincipal, logger)
+            IOptions<Configuration.Configuration> config,
+            IPrincipal currentPrincipal, ILoggerFactory logger) : base(config, repoUser, userManager, currentPrincipal, logger)
         {
             _repoMimeType = repoMimeType ?? throw new ArgumentNullException(nameof(repoMimeType));
             _repoBillingPlan = repoBillingPlan ?? throw new ArgumentNullException(nameof(repoBillingPlan));
@@ -56,7 +58,7 @@ namespace BO.AppServer.Business.Services
             return new ResultsValueDto<MimeTypeRDto>(mimeTypes.MapList<MimeType, MimeTypeRDto>());
         }
 
-        public async Task<ResultValueDto<MimeTypeRDto>> CreateMimeTypeAsync(MimeTypeCDto mimeType)
+        public async Task<ResultValueDto<MimeTypeRDto>> CreateMimeTypeAsync(MimeTypeCDto mimeType, bool isSilent = false)
         {
 
             // Validation
@@ -66,7 +68,8 @@ namespace BO.AppServer.Business.Services
             {
                 var exc = new EntityAlreadyExistsException(typeof(MimeType), mimeType.Mimetype1);
                 Log.LogWarning(exc.Message);
-                throw exc;
+                if (!isSilent)
+                    throw exc;
             }
 
             // Create entity
@@ -118,7 +121,7 @@ namespace BO.AppServer.Business.Services
             return new ResultsValueDto<BillingPlanRDto>(billingPlans.MapList<BillingPlan, BillingPlanRDto>());
         }
 
-        public async Task<ResultValueDto<BillingPlanRDto>> CreateBillingPlanAsync(BillingPlanCDto billingPlan)
+        public async Task<ResultValueDto<BillingPlanRDto>> CreateBillingPlanAsync(BillingPlanCDto billingPlan, bool isSilent = false)
         {
             // Validation
             var exists = _repoBillingPlan.Query(new Paging())
@@ -127,20 +130,23 @@ namespace BO.AppServer.Business.Services
             {
                 var exc = new EntityAlreadyExistsException(typeof(BillingPlan), billingPlan.Code);
                 Log.LogWarning(exc.Message);
-                throw exc;
+                if (!isSilent)
+                    throw exc;
             }
 
             if (billingPlan.Code.Length > 10)
             {
                 var exc = new DataSizeValidationException(typeof(BillingPlan), nameof(BillingPlanCDto.Code), 10);
                 Log.LogWarning(exc.Message);
-                throw exc;
+                if (!isSilent)
+                    throw exc;
             }
             if (billingPlan.PstprocessProfile.Length > 5)
             {
                 var exc = new DataSizeValidationException(typeof(BillingPlan), nameof(BillingPlanCDto.PstprocessProfile), 5);
                 Log.LogWarning(exc.Message);
-                throw exc;
+                if (!isSilent)
+                    throw exc;
             }
 
 

+ 56 - 0
AppServer/Business/Services/ConfigurationService.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Security.Principal;
 using System.Threading.Tasks;
+using BO.AppServer.Metadata.Dto;
 using BO.AppServer.Metadata.Enums;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
@@ -34,6 +35,7 @@ namespace BO.AppServer.Business.Services
             using (var scope = _serviceProvider.CreateScope())
             {
                 var srvUsers = scope.ServiceProvider.GetRequiredService<UserService>();
+                
 
                 await srvUsers.EnsureRolesAsync();
                     
@@ -63,10 +65,63 @@ namespace BO.AppServer.Business.Services
                         RoleEnum.User,
                         RoleEnum.SuperAdmin
                     });
+
             }
             return new ResultPlain();
         }
 
+        public async Task<ResultPlain> InstallDev()
+        {
+
+            using (var scope = _serviceProvider.CreateScope())
+            {
+                var srvCatalogues = scope.ServiceProvider.GetRequiredService<CatalogueService>();
+                var srvUsers = scope.ServiceProvider.GetRequiredService<UserService>();
+                var srvWorkspaces = scope.ServiceProvider.GetRequiredService<WorkspaceService>();
+             
+                await srvCatalogues.CreateBillingPlanAsync(new BillingPlanCDto()
+                {
+                    Name = "Unlimited",
+                    Code = "UNLIMITED",
+                    Description = "This plan is only for testing purpose",
+                    PstinitialCredits = 1000,
+                    PstcreditsPerItem = 1,
+                    Pstwatermark = true,
+                    Pstquality = 1,
+                    PstprocessProfile = "PRC01",
+                    Psttest = true,
+                    Price = 1,
+                    Currency = "EUR",
+                    IsCustom = false,
+                    IsHidden = false,
+                    IsEnabled = true
+                }, true);
+
+                await srvCatalogues.CreateMimeTypeAsync(new MimeTypeCDto()
+                {
+                    Mimetype1 = "text/plain",
+                    Description = "Plain text file",
+                    Extensions = "txt",
+                    IsEnabled = true   
+                }, true);
+
+
+                await EnsureUser(srvUsers, "test", "password","test@bo.com",1029, new[] { RoleEnum.User, RoleEnum.Admin });
+
+                
+                await srvWorkspaces.CreateWorkspaceAsync(new WorkspaceCDto()
+                {
+                    Name = "TestWorkspace",
+                    Apipassword = "test",
+                    BillingPlanCode = "UNLIMITED",
+                    AssignedUserName = "test"
+                });
+            }
+            return new ResultPlain();
+        }
+
+
+
         protected async Task EnsureUser(UserService srvUsers, string userName, string userPassword, string userEmail, int prefferedLCID,
             RoleEnum[] roles)
         {
@@ -78,5 +133,6 @@ namespace BO.AppServer.Business.Services
             else
                 await srvUsers.EnusreUserRolesAsync(userName, roles);
         }
+
     }
 }

+ 3 - 1
AppServer/Business/Services/DocumentService.cs

@@ -13,6 +13,7 @@ using BO.AppServer.Metadata.Dto;
 using BO.AppServer.Metadata.Enums;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
 using Quadarax.Foundation.Core.Data;
 using Quadarax.Foundation.Core.Data.Interface;
 using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
@@ -36,10 +37,11 @@ namespace BO.AppServer.Business.Services
             MetadocumentRepo repoDocument,
             MimeTypeRepo repoMType,
             ArtifactRepo repoArtifact,
+            IOptions<Configuration.Configuration> config,
             UserRepo repoUser, 
             UserManager<IdentityUser> userManager, 
             IPrincipal currentPrincipal, 
-            ILoggerFactory logger) : base(repoUser, userManager, currentPrincipal, logger)
+            ILoggerFactory logger) : base(config, repoUser, userManager, currentPrincipal, logger)
         {
             _repoWorkspace = repoWorkspace ?? throw new ArgumentNullException(nameof(repoWorkspace));
             _repoDocument = repoDocument ?? throw new ArgumentNullException(nameof(repoDocument));

+ 4 - 5
AppServer/Business/Services/UserService.cs

@@ -11,6 +11,7 @@ using BO.AppServer.Metadata.Dto;
 using BO.AppServer.Metadata.Enums;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
 using Quadarax.Foundation.Core.Business.Security;
 using Quadarax.Foundation.Core.Data;
 using Quadarax.Foundation.Core.Data.Interface;
@@ -33,10 +34,11 @@ namespace BO.AppServer.Business.Services
             WorkspaceRepo repoWorkspace,
             AccessService srvAccessService,
             RoleManager<IdentityRole> roleManager, 
+            IOptions<Configuration.Configuration> config,
             UserRepo repoUser,
             UserManager<IdentityUser> userManager,
             IPrincipal currentPrincipal,
-            ILoggerFactory logger) : base(repoUser, userManager, currentPrincipal, logger)
+            ILoggerFactory logger) : base(config, repoUser, userManager, currentPrincipal, logger)
         {
             _manUser = userManager ?? throw new ArgumentNullException(nameof(userManager));
             _manRole = roleManager ?? throw new ArgumentNullException(nameof(roleManager));
@@ -162,10 +164,7 @@ namespace BO.AppServer.Business.Services
             if (user == null)
                     return new ResultBoolDto(false);
 
-
-            var exists = _repoUser.Query(new Paging()).Any(x =>
-                x.Name.ToLower() == userName.ToLower(CultureInfo.InvariantCulture) && x.Ifreference == user.Id);
-            
+            var exists = _repoUser.Query(new Paging()).Any(x => x.Name.ToLower() == userName.ToLower(CultureInfo.InvariantCulture) && x.Ifreference == user.Id);
             return new ResultBoolDto(exists);
         }
 

+ 5 - 2
AppServer/Business/Services/WorkspaceService.cs

@@ -12,6 +12,7 @@ using BO.AppServer.Metadata.Dto;
 using BO.AppServer.Metadata.Enums;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
 using Quadarax.Foundation.Core.Data;
 using Quadarax.Foundation.Core.Data.Interface;
 using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
@@ -29,10 +30,11 @@ namespace BO.AppServer.Business.Services
         #region *** Constructor ***
         public WorkspaceService(WorkspaceRepo repoWorkspace, 
             BillingPlanRepo repoBillingPlan,
+            IOptions<Configuration.Configuration> config,
             UserRepo repoUser, 
             UserManager<IdentityUser> userManager, 
             IPrincipal currentPrincipal, 
-            ILoggerFactory logger) : base(repoUser, userManager, currentPrincipal, logger)
+            ILoggerFactory logger) : base(config, repoUser, userManager, currentPrincipal, logger)
         {
             _repoWorkspace = repoWorkspace ?? throw new ArgumentNullException(nameof(repoWorkspace));
             _repoBillingPlan = repoBillingPlan ?? throw new ArgumentNullException(nameof(repoBillingPlan));
@@ -62,8 +64,9 @@ namespace BO.AppServer.Business.Services
             }
 
             var current = GetCurrentUser();
-            var newWorkspace = _repoWorkspace.NewWorkspace(workspace.Name, billingPlan,true, owner,current);
+            var newWorkspace = _repoWorkspace.CreateWorkspace(workspace.Name, billingPlan, workspace.Apipassword, true, owner,current);
             _repoWorkspace.Commit();
+            Log.LogInformation($"Workspace '{newWorkspace.Name}' [API-KEY:{newWorkspace.Apikey}] created and appends to users: {string.Join(",", newWorkspace.UserWorkspaces.Select(x=>x.User.Name))}");
             return new ResultValueDto<WorkspaceRDto>(newWorkspace.Map<Workspace, WorkspaceRDto>());
         }
 

+ 45 - 5
AppServer/Connector.Console/Connection.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Threading.Tasks;
 using BO.AppServer.Metadata.Dto;
 using BO.AppServer.Metadata.Enums;
@@ -121,12 +122,52 @@ namespace BO.Connector.Console
         #endregion
 
         #region *** Documents ***
-        public async Task<IEnumerable<DocumentRDto>> GetDocumentsAsync(MimeTypeScopeEnums scope,IdentificationTypeEnum identificationType, string identificationValue, PagingDto paging = null)
+        public async Task<IEnumerable<DocumentRDto>> GetDocumentsAsync(DocumentsScopeEnums scope, PagingDto paging = null)
         {
             CheckIsOpen();
-            var result = await CallRequestAsync<ResultsValueDto<DocumentRDto>>($"{Ticket}/documents/{identificationType}/{identificationValue}/{scope}", RestCallTypeEnum.Get,null,GetPagingHeaderAttributes(paging));
+            var result = await CallRequestAsync<ResultsValueDto<DocumentRDto>>($"{Ticket}/documents/{scope}", RestCallTypeEnum.Get,null,GetPagingHeaderAttributes(paging));
             return result.Values;
         }
+
+        public async Task<IEnumerable<DocumentRDto>> GetWorkspaceDocumentsAsync(DocumentsScopeEnums scope, string workspaceApiKey,string apiKeyPassword,string userNameContext, PagingDto paging = null)
+        {
+            CheckIsOpen();
+            var header = GetUserContextHeaderAttributes(userNameContext, GetApiPasswordHeaderAttributes(apiKeyPassword,GetPagingHeaderAttributes(paging)));
+            var result = await CallRequestAsync<ResultsValueDto<DocumentRDto>>($"{Ticket}/workspace/{workspaceApiKey}/documents/{scope}", RestCallTypeEnum.Get,null, header);
+            return result.Values;
+        }
+        public async Task<DocumentRDto> GetWorkspaceDocumentAsync(string workspaceApiKey,string apiKeyPassword,long documentId, string userNameContext)
+        {
+            CheckIsOpen();
+            var header = GetUserContextHeaderAttributes(userNameContext, GetApiPasswordHeaderAttributes(apiKeyPassword));
+            var result = await CallRequestAsync<ResultValueDto<DocumentRDto>>($"{Ticket}/workspace/{workspaceApiKey}/document/{documentId}", RestCallTypeEnum.Get,null, header);
+            return result.Value;
+        }
+
+        public async Task<Stream> GetWorkspaceDocumentContentAsync(string workspaceApiKey,string apiKeyPassword,long documentId, long artifactId, string userNameContext)
+        {
+            CheckIsOpen();
+            var header = GetUserContextHeaderAttributes(userNameContext, GetApiPasswordHeaderAttributes(apiKeyPassword));
+            var result = await CallGetStreamAsync($"{Ticket}/workspace/{workspaceApiKey}/document/{documentId}/artifact/{artifactId}/content", header);
+            return result;
+        }
+
+        public async Task<DocumentRDto> CreateWorkspaceDocumentAsync(string workspaceApiKey,string apiKeyPassword,DocumentCDto data, string userNameContext)
+        {
+            CheckIsOpen();
+            var header = GetUserContextHeaderAttributes(userNameContext, GetApiPasswordHeaderAttributes(apiKeyPassword));
+            var result = await CallRequestAsync<ResultValueDto<DocumentRDto>>($"{Ticket}/workspace/{workspaceApiKey}/document", RestCallTypeEnum.Post,data, header);
+            return result.Value;
+        }
+
+        public async Task<ArtifactRDto> AppendWorkspaceDocumentArtifactAsync(string workspaceApiKey,string apiKeyPassword,long documentId, ArtifactCDto data,Stream contentStream, string userNameContext)
+        {
+            CheckIsOpen();
+            var header = GetUserContextHeaderAttributes(userNameContext, GetApiPasswordHeaderAttributes(apiKeyPassword));
+            var result = await CallPostStreamMultipartAsync<ResultValueDto<ArtifactRDto>>($"{Ticket}/workspace/{workspaceApiKey}/document/{documentId}/artifact/input", data, contentStream, header);
+            return result.Value;
+        }
+
         #endregion
 
 
@@ -138,11 +179,10 @@ namespace BO.Connector.Console
             return result.Value;
         }
 
-        public async Task<IEnumerable<WorkspaceRDto>> GetWorkspacesAsync(WorkspaceScopeEnums scope,string userContext, PagingDto paging = null)
+        public async Task<IEnumerable<WorkspaceRDto>> GetWorkspacesAsync(WorkspaceScopeEnums scope,string userNameContext, PagingDto paging = null)
         {
             CheckIsOpen();
-            var headers = GetPagingHeaderAttributes(paging);
-            headers.Add("context", userContext);
+            var headers = GetUserContextHeaderAttributes(userNameContext, GetPagingHeaderAttributes(paging));
             var result = await CallRequestAsync<ResultsValueDto<WorkspaceRDto>>($"{Ticket}/workspaces/{scope}", RestCallTypeEnum.Get,null,headers);
             return result.Values;
         }

+ 80 - 1
AppServer/Connector/AbstractConnection.cs

@@ -127,11 +127,14 @@ namespace BO.Connector
             Log(LogSeverityEnum.Info,$"User '{result.Result.Value.Name}' is logged in.");
         }
 
-        protected IDictionary<string, string> GetPagingHeaderAttributes(PagingDto paging)
+        protected IDictionary<string, string> GetPagingHeaderAttributes(PagingDto paging, IDictionary<string,string> source = null)
         {
             if (paging == null || paging.IsDisabled)
                 return null;//paging = new PagingDto();
 
+            if (source == null)
+                source = new Dictionary<string, string>();
+
             var result = new Dictionary<string, string>
             {
                 { "page", paging.Page.ToString() },
@@ -140,6 +143,32 @@ namespace BO.Connector
             return result;
         }
 
+        protected IDictionary<string, string> GetApiPasswordHeaderAttributes(string apiKeyPassword, IDictionary<string,string> source = null)
+        {
+            if (source == null)
+                source = new Dictionary<string, string>();
+
+            var result = new Dictionary<string, string>
+            {
+                { "apiKeyPassword", apiKeyPassword },
+            };
+            return result;
+        }
+
+        protected IDictionary<string, string> GetUserContextHeaderAttributes(string userNameContext, IDictionary<string,string> source = null)
+        {
+            if (source == null)
+                source = new Dictionary<string, string>();
+
+            var result = new Dictionary<string, string>
+            {
+                { "context", userNameContext },
+            };
+            return result;
+        }
+
+
+
         protected async Task<Stream> CallGetStreamAsync(string relativeUrlApiCall,
             IDictionary<string, string> headerAttributes = null, bool silent = false)
         {
@@ -152,9 +181,59 @@ namespace BO.Connector
                     _client.DefaultRequestHeaders.Add(key,headerAttributes[key]);
                 }
             }
+
+         
             return await _client.GetStreamAsync(relativeUrlApiCall);
         }
 
+        protected async Task<TResult> CallPostStreamMultipartAsync<TResult>(string relativeUrlApiCall,
+            IDto data,Stream stream, IDictionary<string, string> headerAttributes = null, bool silent = false)
+            where TResult : ResultDto
+        {
+            Log(LogSeverityEnum.Trace, $"Calling REST API POST-MULTI-STREAM {_uriApiBase.AbsoluteUri + relativeUrlApiCall}");
+
+            var rqData = new StringContent(_binder.SaveToString(data));
+            var rqStream = new StreamContent(stream);
+            var req = new MultipartContent();
+            req.Add(rqData);
+            req.Add(rqStream);
+            if (headerAttributes!=null)
+                foreach (var key in headerAttributes.Keys)
+                    req.Headers.Add(key,headerAttributes[key]);
+            req.Headers.ContentType = new MediaTypeHeaderValue("application/json");
+            var start = DateTime.Now;
+            var resp = await _client.PostAsync(relativeUrlApiCall, req);
+         
+         
+            Log(LogSeverityEnum.Trace, $"REST API POST-MULTI-STREAM {_uriApiBase.AbsoluteUri + relativeUrlApiCall} done @ {(DateTime.Now - start).ToReadableString()}");
+            if (!resp.IsSuccessStatusCode)
+            {
+                var message = $"Calling REST API POST-MULTI-STREAM {_uriApiBase.AbsoluteUri + relativeUrlApiCall} ends with result code '{resp.StatusCode}'";
+                Log(LogSeverityEnum.Warn, message);
+                throw new Exception(message);
+            }
+
+            var content = await resp.Content.ReadAsStringAsync();
+            if (_isDumpContentEnabled)
+                Log(LogSeverityEnum.Trace, content);
+
+            var result = (TResult)_binder.LoadFromString(content, typeof(TResult));
+            if (result.IsSuccess) return result;
+            if (silent) return result;
+
+            // handle errors
+            var excps = new List<Exception>();
+            foreach (var err in result.Errors)
+            {
+                var exc = new Exception($"[{err.Code}] {err.Message}");
+                exc.Data.Add("Code", err.Code);
+                excps.Add(exc);
+            }
+
+            throw new AggregateException(excps);
+        }
+
+
         protected async Task<TResult> CallRequestAsync<TResult>(string relativeUrlApiCall,RestCallTypeEnum method, IDto data = null,IDictionary<string,string> headerAttributes = null, bool silent = false) 
             where TResult : ResultDto
         {

+ 86 - 20
AppServer/Data/Entity/BOContext.cs

@@ -1,6 +1,5 @@
 using System;
 using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Metadata;
 using Quadarax.Foundation.Core.Data.Domain;
 
 #nullable disable
@@ -9,6 +8,7 @@ namespace BO.AppServer.Data.Entity
 {
     public partial class BOContext : DataDomain
     {
+
         public BOContext(DbContextOptions<BOContext> options)
             : base(options)
         {
@@ -24,6 +24,7 @@ namespace BO.AppServer.Data.Entity
         public virtual DbSet<MetadocumentBilling> MetadocumentBillings { get; set; }
         public virtual DbSet<MetadocumentTag> MetadocumentTags { get; set; }
         public virtual DbSet<MimeType> MimeTypes { get; set; }
+        public virtual DbSet<Registration> Registrations { get; set; }
         public virtual DbSet<Statistic> Statistics { get; set; }
         public virtual DbSet<StatusHistory> StatusHistories { get; set; }
         public virtual DbSet<Structure> Structures { get; set; }
@@ -626,9 +627,7 @@ namespace BO.AppServer.Data.Entity
 
                 entity.ToTable("MetadocumentBilling");
 
-                entity.HasComment("Association of metadocument and billing plan");
-
-                entity.Property(e => e.BillingPlanId).HasComment("Reference to billing plan");
+                entity.HasComment("Association of metadocument and billing plan with properties. Stores information about processed documents (name, status timestamps, etc.) relates to workspace billing plan selection.");
 
                 entity.Property(e => e.Created)
                     .HasColumnType("datetime")
@@ -637,34 +636,55 @@ namespace BO.AppServer.Data.Entity
 
                 entity.Property(e => e.CreditCost).HasComment("Numeric value of billing plan spending. Depends on BillingPlan.");
 
+                entity.Property(e => e.Downloaded)
+                    .HasColumnType("datetime")
+                    .HasComment("Timestamp when document was last downloaded");
+
                 entity.Property(e => e.MetadocumentId).HasComment("Reference to owning metadocument");
 
                 entity.Property(e => e.Modified)
                     .HasColumnType("datetime")
                     .HasComment("Timestamp when billing was modified");
 
+                entity.Property(e => e.Procesed)
+                    .HasColumnType("datetime")
+                    .HasComment("Timestamp when document was processed");
+
                 entity.Property(e => e.ProcessProfile)
                     .HasMaxLength(5)
                     .IsUnicode(false)
                     .HasComment("Processing profile code");
 
+                entity.Property(e => e.ProcessStart)
+                    .HasColumnType("datetime")
+                    .HasComment("Timestamp when document set to processing state");
+
+                entity.Property(e => e.ProcessState).HasComment("Last state of processing (OK,Fail)");
+
+                entity.Property(e => e.Psinstance)
+                    .HasMaxLength(100)
+                    .IsUnicode(false)
+                    .HasColumnName("PSInstance")
+                    .HasComment("Process server instance identifier");
+
                 entity.Property(e => e.Quality).HasComment("Process quality 0 = lowest");
 
                 entity.Property(e => e.Test).HasComment("Flag if testing mode");
 
                 entity.Property(e => e.Watermark).HasComment("Flag if watermarked");
 
-                entity.HasOne(d => d.BillingPlan)
-                    .WithMany()
-                    .HasForeignKey(d => d.BillingPlanId)
-                    .OnDelete(DeleteBehavior.ClientSetNull)
-                    .HasConstraintName("REL_MetadocumentBilling_BillingPlan");
+                entity.Property(e => e.WorkspaceBillingId).HasComment("Reference to workspace billing plan");
 
                 entity.HasOne(d => d.Metadocument)
                     .WithMany()
                     .HasForeignKey(d => d.MetadocumentId)
-                    .OnDelete(DeleteBehavior.ClientSetNull)
                     .HasConstraintName("REL_MetadocumentBilling_Metadocument");
+
+                entity.HasOne(d => d.WorkspaceBilling)
+                    .WithMany()
+                    .HasForeignKey(d => d.WorkspaceBillingId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("REL_MetadocumentBilling_WorkspaceBilling");
             });
 
             modelBuilder.Entity<MetadocumentTag>(entity =>
@@ -743,12 +763,53 @@ namespace BO.AppServer.Data.Entity
                     .HasConstraintName("REL_MimeType_User_Modified");
             });
 
+            modelBuilder.Entity<Registration>(entity =>
+            {
+                entity.ToTable("Registration");
+
+                entity.HasComment("Holds Process Server registrations");
+
+                entity.Property(e => e.Id).HasComment("Primary key of Registration record");
+
+                entity.Property(e => e.Created)
+                    .HasColumnType("datetime")
+                    .HasDefaultValueSql("(getdate())")
+                    .HasComment("Timestamp when registration was created");
+
+                entity.Property(e => e.DocumentFailedCnt).HasComment("# of failed documents");
+
+                entity.Property(e => e.DocumentProcessedCnt).HasComment("# of new processed documents");
+
+                entity.Property(e => e.LastActivity)
+                    .HasColumnType("datetime")
+                    .HasComment("Timestamp latest activity");
+
+                entity.Property(e => e.LocationIp)
+                    .HasMaxLength(100)
+                    .IsUnicode(false)
+                    .HasColumnName("LocationIP")
+                    .HasComment("Process server instance identifier");
+
+                entity.Property(e => e.Modified)
+                    .HasColumnType("datetime")
+                    .HasComment("Timestamp when registration was modified");
+
+                entity.Property(e => e.Psinstance)
+                    .HasMaxLength(100)
+                    .IsUnicode(false)
+                    .HasColumnName("PSInstance")
+                    .HasComment("Process server instance identifier");
+            });
+
             modelBuilder.Entity<Statistic>(entity =>
             {
                 entity.ToTable("Statistic");
 
                 entity.HasComment("Holds statistics information on daily base");
 
+                entity.HasIndex(e => new { e.Year, e.Month, e.Day }, "IDX_DATE")
+                    .IsUnique();
+
                 entity.Property(e => e.Id).HasComment("Primary key of Statistic record");
 
                 entity.Property(e => e.Created)
@@ -954,6 +1015,12 @@ namespace BO.AppServer.Data.Entity
 
                 entity.HasComment("User identity with properties");
 
+                entity.HasIndex(e => e.Ifreference, "IDX_IFREFERENCE")
+                    .IsUnique();
+
+                entity.HasIndex(e => e.Name, "IDX_USER_NAME")
+                    .IsUnique();
+
                 entity.Property(e => e.Id).HasComment("User primary key");
 
                 entity.Property(e => e.Created)
@@ -1001,7 +1068,7 @@ namespace BO.AppServer.Data.Entity
 
             modelBuilder.Entity<UserWorkspace>(entity =>
             {
-                entity.HasNoKey();
+                // entity.HasNoKey();
 
                 entity.ToTable("UserWorkspace");
 
@@ -1069,11 +1136,10 @@ namespace BO.AppServer.Data.Entity
                     .HasMaxLength(200)
                     .HasComment("Workspace name");
 
-                entity.HasOne(d => d.BillingInfo)
-                    .WithMany(p => p.Workspaces)
-                    .HasForeignKey(d => d.BillingInfoId)
-                    .OnDelete(DeleteBehavior.ClientSetNull)
-                    .HasConstraintName("REL_Workspace_BillingInfo");
+                //entity.HasOne(d => d.BillingInfo)
+                //    .WithMany(p => p.Workspaces)
+                //    .HasForeignKey(d => d.BillingInfoId)
+                //    .HasConstraintName("REL_Workspace_BillingInfo");
 
                 entity.HasOne(d => d.CreatedByUser)
                     .WithMany(p => p.WorkspaceCreatedByUsers)
@@ -1089,12 +1155,12 @@ namespace BO.AppServer.Data.Entity
 
             modelBuilder.Entity<WorkspaceBilling>(entity =>
             {
-                entity.HasNoKey();
-
                 entity.ToTable("WorkspaceBilling");
 
                 entity.HasComment("Deffines current state of billing plan for workspace");
 
+                entity.Property(e => e.Id).HasComment("Primary key of WorkspaceBilling record");
+
                 entity.Property(e => e.BillingPlanId).HasComment("Reference to billing plan");
 
                 entity.Property(e => e.Created)
@@ -1143,13 +1209,13 @@ namespace BO.AppServer.Data.Entity
                 entity.Property(e => e.WorkspaceId).HasComment("Reference to owning workspace");
 
                 entity.HasOne(d => d.BillingPlan)
-                    .WithMany()
+                    .WithMany(p => p.WorkspaceBillings)
                     .HasForeignKey(d => d.BillingPlanId)
                     .OnDelete(DeleteBehavior.ClientSetNull)
                     .HasConstraintName("REL_WorkspaceBilling_BillingPlan");
 
                 entity.HasOne(d => d.Workspace)
-                    .WithMany()
+                    .WithMany(p => p.WorkspaceBillings)
                     .HasForeignKey(d => d.WorkspaceId)
                     .OnDelete(DeleteBehavior.ClientSetNull)
                     .HasConstraintName("REL_WorkspaceBilling_Workspace");

+ 38 - 0
AppServer/Data/Entity/BOContext.decl.cs

@@ -0,0 +1,38 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace BO.AppServer.Data.Entity
+{
+    public partial class BOContext
+    {
+        partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
+        {
+            modelBuilder.Entity<Workspace>(entity =>
+                {
+                    // WORKAROUND temporary solution for keyless entity
+                    //modelBuilder.Entity<UserWorkspace>()
+                    //    .HasAlternateKey(x => x.Id);
+                    
+                    modelBuilder.Entity<UserWorkspace>()
+                        .HasKey(t => new { t.WorkspaceId, t.UserId });
+                        
+
+                    modelBuilder.Entity<UserWorkspace>()
+                        .HasOne(am => am.User)
+                        .WithMany(a => a.UserWorkspaces)
+                        .HasForeignKey(am => am.UserId);
+
+                    modelBuilder.Entity<UserWorkspace>()
+                        .HasOne(am => am.Workspace)
+                        .WithMany(m => m.UserWorkspaces)
+                        .HasForeignKey(am => am.WorkspaceId);
+
+
+                    modelBuilder.Entity<Workspace>().HasOne(d => d.BillingInfo)
+                    .WithOne(p => p.Workspace)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("REL_Workspace_BillingInfo");
+                }
+            );
+        }
+    }
+}

+ 1 - 1
AppServer/Data/Entity/BillingInfo.cs

@@ -12,7 +12,7 @@ namespace BO.AppServer.Data.Entity
             Workspaces = new HashSet<Workspace>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public long WorkspaceId { get; set; }
         public string SubjectName { get; set; }
         public string Address1 { get; set; }

+ 3 - 1
AppServer/Data/Entity/BillingPlan.cs

@@ -10,9 +10,10 @@ namespace BO.AppServer.Data.Entity
         public BillingPlan()
         {
             InvoiceItems = new HashSet<InvoiceItem>();
+            WorkspaceBillings = new HashSet<WorkspaceBilling>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public string Name { get; set; }
         public string Code { get; set; }
         public string Description { get; set; }
@@ -35,5 +36,6 @@ namespace BO.AppServer.Data.Entity
         public virtual User CreatedByUser { get; set; }
         public virtual User ModifiedByUser { get; set; }
         public virtual ICollection<InvoiceItem> InvoiceItems { get; set; }
+        public virtual ICollection<WorkspaceBilling> WorkspaceBillings { get; set; }
     }
 }

+ 1 - 1
AppServer/Data/Entity/Invoice.cs

@@ -12,7 +12,7 @@ namespace BO.AppServer.Data.Entity
             InvoiceItems = new HashSet<InvoiceItem>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public long WorkspaceId { get; set; }
         public long InvoiceIssuerId { get; set; }
         public string Code { get; set; }

+ 1 - 1
AppServer/Data/Entity/InvoiceIssuer.cs

@@ -12,7 +12,7 @@ namespace BO.AppServer.Data.Entity
             Invoices = new HashSet<Invoice>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public string SubjectName { get; set; }
         public string Address1 { get; set; }
         public string Address2 { get; set; }

+ 1 - 1
AppServer/Data/Entity/InvoiceItem.cs

@@ -7,7 +7,7 @@ namespace BO.AppServer.Data.Entity
 {
     public partial class InvoiceItem
     {
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public long InvoiceId { get; set; }
         public long BillingPlanId { get; set; }
         public string BillingPlanCode { get; set; }

+ 1 - 1
AppServer/Data/Entity/Metadocument.cs

@@ -13,7 +13,7 @@ namespace BO.AppServer.Data.Entity
             StatusHistories = new HashSet<StatusHistory>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public long StructureId { get; set; }
         public string Name { get; set; }
         public int Status { get; set; }

+ 8 - 3
AppServer/Data/Entity/MetadocumentBilling.cs

@@ -7,17 +7,22 @@ namespace BO.AppServer.Data.Entity
 {
     public partial class MetadocumentBilling
     {
-        public long MetadocumentId { get; set; }
-        public long BillingPlanId { get; set; }
+        public long? MetadocumentId { get; set; }
+        public long WorkspaceBillingId { get; set; }
         public int CreditCost { get; set; }
         public bool Watermark { get; set; }
         public int Quality { get; set; }
         public string ProcessProfile { get; set; }
         public bool Test { get; set; }
+        public DateTime? Procesed { get; set; }
+        public DateTime? ProcessStart { get; set; }
+        public DateTime? Downloaded { get; set; }
+        public int ProcessState { get; set; }
+        public string Psinstance { get; set; }
         public DateTime Created { get; set; }
         public DateTime? Modified { get; set; }
 
-        public virtual BillingPlan BillingPlan { get; set; }
         public virtual Metadocument Metadocument { get; set; }
+        public virtual WorkspaceBilling WorkspaceBilling { get; set; }
     }
 }

+ 1 - 1
AppServer/Data/Entity/MimeType.cs

@@ -12,7 +12,7 @@ namespace BO.AppServer.Data.Entity
             Artifacts = new HashSet<Artifact>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public string Mimetype1 { get; set; }
         public string Extensions { get; set; }
         public string Description { get; set; }

+ 19 - 0
AppServer/Data/Entity/Registration.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+
+#nullable disable
+
+namespace BO.AppServer.Data.Entity
+{
+    public partial class Registration
+    {
+        public long Id { get; set; }
+        public string Psinstance { get; set; }
+        public string LocationIp { get; set; }
+        public DateTime? LastActivity { get; set; }
+        public int DocumentProcessedCnt { get; set; }
+        public int DocumentFailedCnt { get; set; }
+        public DateTime Created { get; set; }
+        public DateTime? Modified { get; set; }
+    }
+}

+ 9 - 0
AppServer/Data/Entity/Registration.decl.cs

@@ -0,0 +1,9 @@
+using Quadarax.Foundation.Core.Data.Entity;
+using Quadarax.Foundation.Core.Data.Interface.Entity;
+
+namespace BO.AppServer.Data.Entity
+{
+    public partial class Registration :  Entity<long>, IDao<long>
+    {
+    }
+}

+ 1 - 1
AppServer/Data/Entity/Statistic.cs

@@ -7,7 +7,7 @@ namespace BO.AppServer.Data.Entity
 {
     public partial class Statistic
     {
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public int Year { get; set; }
         public int Month { get; set; }
         public int Day { get; set; }

+ 1 - 1
AppServer/Data/Entity/StatusHistory.cs

@@ -7,7 +7,7 @@ namespace BO.AppServer.Data.Entity
 {
     public partial class StatusHistory
     {
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public long MetadocumentId { get; set; }
         public int Status { get; set; }
         public string Message { get; set; }

+ 1 - 1
AppServer/Data/Entity/Structure.cs

@@ -13,7 +13,7 @@ namespace BO.AppServer.Data.Entity
             Metadocuments = new HashSet<Metadocument>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public string Name { get; set; }
         public long WorkspaceId { get; set; }
         public long? ParentId { get; set; }

+ 1 - 1
AppServer/Data/Entity/Tag.cs

@@ -7,7 +7,7 @@ namespace BO.AppServer.Data.Entity
 {
     public partial class Tag
     {
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public long WorkspaceId { get; set; }
         public string Name { get; set; }
         public string Rgb { get; set; }

+ 1 - 1
AppServer/Data/Entity/User.cs

@@ -32,7 +32,7 @@ namespace BO.AppServer.Data.Entity
             WorkspaceModifiedByUsers = new HashSet<Workspace>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public string Ifreference { get; set; }
         public string Name { get; set; }
         public DateTime? LastLogged { get; set; }

+ 3 - 1
AppServer/Data/Entity/User.decl.cs

@@ -1,9 +1,11 @@
-using Quadarax.Foundation.Core.Data.Entity;
+using System.Collections.Generic;
+using Quadarax.Foundation.Core.Data.Entity;
 using Quadarax.Foundation.Core.Data.Interface.Entity;
 
 namespace BO.AppServer.Data.Entity
 {
     public partial class User :  Entity<long>, IDao<long>
     {
+        public virtual ICollection<UserWorkspace> UserWorkspaces { get; set; }
     }
 }

+ 14 - 0
AppServer/Data/Entity/UserWorkspace.decl.cs

@@ -0,0 +1,14 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+
+
+namespace BO.AppServer.Data.Entity
+{
+    //[Keyless]
+    public partial class UserWorkspace
+    {
+        
+       // WORKAROUND temporary solution for keyless entity
+       //public Guid Id { get; set; } = Guid.NewGuid();
+    }
+}

+ 4 - 2
AppServer/Data/Entity/Workspace.cs

@@ -13,11 +13,12 @@ namespace BO.AppServer.Data.Entity
             Invoices = new HashSet<Invoice>();
             Structures = new HashSet<Structure>();
             Tags = new HashSet<Tag>();
+            WorkspaceBillings = new HashSet<WorkspaceBilling>();
         }
 
-        // public long Id { get; set; }
+        public long Id { get; set; }
         public string Name { get; set; }
-        public long BillingInfoId { get; set; }
+        public long? BillingInfoId { get; set; }
         public long BillingPlanId { get; set; }
         public Guid Apikey { get; set; }
         public string Apipassword { get; set; }
@@ -34,5 +35,6 @@ namespace BO.AppServer.Data.Entity
         public virtual ICollection<Invoice> Invoices { get; set; }
         public virtual ICollection<Structure> Structures { get; set; }
         public virtual ICollection<Tag> Tags { get; set; }
+        public virtual ICollection<WorkspaceBilling> WorkspaceBillings { get; set; }
     }
 }

+ 4 - 2
AppServer/Data/Entity/Workspace.decl.cs

@@ -1,10 +1,12 @@
-using Quadarax.Foundation.Core.Data.Entity;
+using System.Collections.Generic;
+using Quadarax.Foundation.Core.Data.Entity;
 using Quadarax.Foundation.Core.Data.Interface.Entity;
 
 namespace BO.AppServer.Data.Entity
 {
     public partial class Workspace :  Entity<long>, IDao<long>
-
     {
+        public virtual ICollection<UserWorkspace> UserWorkspaces { get; set; }
+
     }
 }

+ 1 - 0
AppServer/Data/Entity/WorkspaceBilling.cs

@@ -7,6 +7,7 @@ namespace BO.AppServer.Data.Entity
 {
     public partial class WorkspaceBilling
     {
+        public long Id { get; set; }
         public long WorkspaceId { get; set; }
         public long BillingPlanId { get; set; }
         public DateTime Created { get; set; }

+ 10 - 0
AppServer/Data/Entity/WorkspaceBilling.decl.cs

@@ -0,0 +1,10 @@
+using Quadarax.Foundation.Core.Data.Entity;
+using Quadarax.Foundation.Core.Data.Interface.Entity;
+
+namespace BO.AppServer.Data.Entity
+{
+    public partial class WorkspaceBilling :  Entity<long>, IDao<long>
+
+    {
+    }
+}

+ 14 - 0
AppServer/Data/Repository/RegistrationRepo.cs

@@ -0,0 +1,14 @@
+using BO.AppServer.Data.Entity;
+using Quadarax.Foundation.Core.Data.Domain;
+using Quadarax.Foundation.Core.Data.Interface.Domain;
+using Quadarax.Foundation.Core.Data.Repository;
+
+namespace BO.AppServer.Data.Repository
+{
+    public class RegistrationRepo : EntityRepository<long,  Registration>
+    {
+        public RegistrationRepo(IUnitOfWork<DataDomain> unitOfWork) : base(unitOfWork)
+        {
+        }
+    }
+}

+ 14 - 3
AppServer/Data/Repository/WorkspaceRepo.cs

@@ -15,26 +15,37 @@ public class WorkspaceRepo : EntityRepository<long,  Workspace>
         {
         }
 
-        public Workspace NewWorkspace(string name, BillingPlan billingPlan, bool isDefault, User owner, User creator)
+        public Workspace CreateWorkspace(string name, BillingPlan billingPlan, string apiKeyPassword, bool isDefault, User owner, User creator)
         {
             var workspace = New();
+            workspace.Name = name;
+            workspace.BillingPlanId = billingPlan.Id;
             workspace.Created = DateTime.Now;
             workspace.CreatedByUser = creator;
+            workspace.Apikey = Guid.NewGuid();
+            workspace.Apipassword = apiKeyPassword;
             if (workspace.Structures == null)
                 workspace.Structures = new List<Structure>();
+            
             workspace.Structures.Add(new Structure(){Created = DateTime.Now,CreatedByUserId = creator.Id});
+            workspace.UserWorkspaces = new List<UserWorkspace>();
+
             AppendUser(workspace, owner, isDefault);
             return workspace;
         }
 
         public void AppendUser(Workspace workspace, User user, bool isDefault)
         {
-            var userWorkspaceSet = Context.GetDbSet<DbSet<UserWorkspace>>();
             var userWorkspace = new UserWorkspace();
             userWorkspace.Workspace = workspace;
             userWorkspace.User = user;
             userWorkspace.IsDefault = isDefault;
-            userWorkspaceSet.Add(userWorkspace);
+            if (isDefault)
+            {
+                foreach (var uw in workspace.UserWorkspaces)
+                    uw.IsDefault = false;
+            }
+            workspace.UserWorkspaces.Add(userWorkspace);
         }
 
         public IQueryable<Workspace> GetAllEmpty(IPaging paging)

+ 24 - 1
AppServer/Data/readme.txt

@@ -7,4 +7,27 @@ To reverse update:
 - Run following command
 Scaffold-DbContext "Server=(local);Database=BO;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Entity -Force
 - Go to file BOContext.cs and replace class declaration as : public partial class BOContext : DataDomain
-- replace in all entities // public long Id { get; set; } -> // // public long Id { get; set; }
+- replace in all entities // // public long Id { get; set; } -> // // // public long Id { get; set; }
+- replace in BOContext.cs occurency [ln cca:1069]:
+modelBuilder.Entity<UserWorkspace>(entity =>
+            {
+                entity.HasNoKey();
+
+to:
+
+modelBuilder.Entity<UserWorkspace>(entity =>
+            {
+                // entity.HasNoKey();
+
+- replace in BOContext.cs occurency [ln cca:1139]:
+entity.HasOne(d => d.BillingInfo)
+                    .WithMany(p => p.Workspaces)
+                    .HasForeignKey(d => d.BillingInfoId)
+                    .HasConstraintName("REL_Workspace_BillingInfo");
+
+to:
+
+//entity.HasOne(d => d.BillingInfo)
+//                    .WithMany(p => p.Workspaces)
+//                    .HasForeignKey(d => d.BillingInfoId)
+//                    .HasConstraintName("REL_Workspace_BillingInfo");

+ 3 - 3
AppServer/Web/Services/ConsoleController.cs

@@ -180,7 +180,7 @@ namespace BO.AppServer.Web.Services
         }
 
         [HttpGet("{Ticket}/workspace/{wrkspApiKey}/document/{documentId}/artifact/{artifactId}/content")]
-        public async Task<IActionResult> GetAllWorkspaceDocumentArtifactContent(string ticket, string wrkspApiKey,long documentId,long artifactId,[FromHeader] string apiKeyPassword,  [FromHeader] string context)
+        public async Task<IActionResult> GetWorkspaceDocumentArtifactContent(string ticket, string wrkspApiKey,long documentId,long artifactId,[FromHeader] string apiKeyPassword,  [FromHeader] string context)
         {
             // TODO: May wrap to better way
             try
@@ -208,8 +208,8 @@ namespace BO.AppServer.Web.Services
             });
         }
 
-        [HttpPost("{Ticket}/workspace/{wrkspApiKey}/document/{documentId}/artifact/{artifactId}/content/input")]
-        public async Task<ResultValueDto<ArtifactRDto>> AppendWorkspaceDocumentArtifact(string ticket, string wrkspApiKey, long documentId, long artifactId,[FromHeader] string apiKeyPassword, [FromHeader] string context, [FromBody] ArtifactCDto artifact, IFormFile content)
+        [HttpPost("{Ticket}/workspace/{wrkspApiKey}/document/{documentId}/artifact/input")]
+        public async Task<ResultValueDto<ArtifactRDto>> AppendWorkspaceDocumentArtifact(string ticket, string wrkspApiKey, long documentId,[FromHeader] string apiKeyPassword, [FromHeader] string context, [FromBody] ArtifactCDto artifact, IFormFile content)
         {
             CheckAccess(ticket);
             return await Call(async () =>

+ 11 - 0
AppServer/Web/Startup.cs

@@ -1,4 +1,5 @@
 using System;
+using System.IO.Abstractions;
 using System.Security.Principal;
 using BO.AppServer.Business.Configuration;
 using BO.AppServer.Business.Services;
@@ -22,6 +23,7 @@ namespace AppServer
     public class Startup
     {
         private ConfigurationService _srvConfiguration;
+        private IWebHostEnvironment _env;
 
         public Startup(IConfiguration configuration)
         {
@@ -45,6 +47,9 @@ namespace AppServer
             .AddEntityFrameworkStores<IFDbContext>()
             .AddDefaultTokenProviders();
 
+            //Use file abstractions
+            services.AddSingleton<IFileSystem,FileSystem>();
+
             // Inject IPrincipal to get current user in all levels
             services.AddHttpContextAccessor();
             services.AddTransient<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>().HttpContext?.User);
@@ -96,6 +101,8 @@ namespace AppServer
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
         public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, IServiceProvider service)
         {
+            _env = env;
+
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
@@ -142,6 +149,10 @@ namespace AppServer
         private void OnApplicationStarted()
         {
             _srvConfiguration.Install();
+            if (_env.IsDevelopment())
+            {
+                _srvConfiguration.InstallDev();
+            }
         }
     }
 }

+ 1 - 1
AppServer/Web/appsettings.Development.json

@@ -6,7 +6,7 @@
       // Enable components logging
       "Microsoft.Hosting.Lifetime": "Information",
       // Enable EF logging
-      "Microsoft.EntityFrameworkCore.Database.Command": "Information"
+      // "Microsoft.EntityFrameworkCore.Database.Command": "Information"
     }
   },
   "Bo": {

+ 1 - 1
AppServer/Web/appsettings.json

@@ -6,7 +6,7 @@
       // Enable components logging
       "Microsoft.Hosting.Lifetime": "Information",
       // Enable EF logging
-      "Microsoft.EntityFrameworkCore.Database.Command": "Information"
+      // "Microsoft.EntityFrameworkCore.Database.Command": "Information"
     }
   },
   "Bo": {

+ 1 - 0
Common/qdr.fnd.core.business/AbstractService.cs

@@ -34,6 +34,7 @@ namespace Quadarax.Foundation.Core.Business
         {
             return new ResultPlain();
         }
+
         #endregion
     }
 }

+ 1 - 1
Common/qdr.fnd.core.data.itfc/Repository/IDaoRepository.cs

@@ -7,7 +7,7 @@ namespace Quadarax.Foundation.Core.Data.Interface.Repository
 {
     public interface IDaoRepository<TKey, TDao> : IRepository where TDao : IDao<TKey> where TKey : IEquatable<TKey>
     {
-        public IQueryable<TDao> Query(IPaging paging);
+        public IQueryable<TDao> Query(IPaging paging, bool usingUncomited = false);
         public TDao Get(TKey id);
         public IQueryable<TDao> Get(IEnumerable<TKey> ids);
         public TDao Set(TDao entity);

+ 5 - 2
Common/qdr.fnd.core.data/Repository/EntityRepository.cs

@@ -25,11 +25,14 @@ namespace Quadarax.Foundation.Core.Data.Repository
             //_dbSet = domain.GetDbSet<DbSet<TEntity>>();
         }
 
-        public virtual IQueryable<TEntity> Query(IPaging paging)
+        public virtual IQueryable<TEntity> Query(IPaging paging,bool usingUncommited=false)
         {
             var local = DbSetInstance.Local.Page(paging.IsDisabled ? (int?) null : paging.Page, paging.PageSize);
-            if (local.Any())
+            if (local.Any() && usingUncommited)
+            {
                 return local.AsQueryable();
+            }
+
             return DbSetInstance.Page(paging.IsDisabled ? (int?) null : paging.Page, paging.PageSize);
         }