Prechádzať zdrojové kódy

add workspace command support

Dalibor Votruba 4 rokov pred
rodič
commit
cd97259fd9

+ 1 - 0
AppServer/Business/Services/CatalogueService.cs

@@ -132,6 +132,7 @@ namespace BO.AppServer.Business.Services
 
             // Create entity
             var newBillingPlan = _repoBillingPlan.New();
+            billingPlan.Code = billingPlan.Code.ToUpper();
             billingPlan.CopyToDto(newBillingPlan);
             newBillingPlan.Created = DateTime.Now;
             newBillingPlan.CreatedByUser = GetCurrentUser();

+ 97 - 0
AppServer/Business/Services/WorkspaceService.cs

@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Principal;
+using System.Threading.Tasks;
+using BO.AppServer.Business.Exceptions;
+using BO.AppServer.Business.Mapper;
+using BO.AppServer.Business.Services.Base;
+using BO.AppServer.Data.Entity;
+using BO.AppServer.Metadata.Dto;
+using BO.AppServer.Metadata.Enums;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Logging;
+using Quadarax.Foundation.Core.Data.Interface;
+using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
+
+namespace BO.AppServer.Business.Services
+{
+    public class WorkspaceService: UserContextService
+    {
+        #region *** Private fields ***
+        private readonly WorkspaceRepo _repoWorkspace;
+        private readonly BillingPlanRepo _repoBillingPlan;
+        #endregion
+
+        #region *** Constructor ***
+        public WorkspaceService(WorkspaceRepo repoWorkspace, 
+            BillingPlanRepo repoBillingPlan,
+            UserRepo repoUser, 
+            UserManager<IdentityUser> userManager, 
+            IPrincipal currentPrincipal, 
+            ILoggerFactory logger) : base(repoUser, userManager, currentPrincipal, logger)
+        {
+            _repoWorkspace = repoWorkspace ?? throw new ArgumentNullException(nameof(repoWorkspace));
+            _repoBillingPlan = repoBillingPlan ?? throw new ArgumentNullException(nameof(repoBillingPlan));
+
+        }
+        #endregion
+
+
+        #region *** Public Operations ***
+
+        public async Task<ResultValueDto<WorkspaceRDto>> CreateWorkspaceAsync(WorkspaceCDto workspace)
+        {
+            var billingPlan = _repoBillingPlan.GetByCode(workspace.BillingPlanCode);
+            if (billingPlan == null)
+            {
+                var exc = new EntityNotExistsException(typeof(BillingPlan), workspace.BillingPlanCode, 0);
+                Log.LogWarning(exc.Message);
+                throw exc;
+            }
+
+            var owner = _repoUser.GetByName(workspace.AssignedUserName);
+            if (owner == null)
+            {
+                var exc = new EntityNotExistsException(typeof(User), workspace.AssignedUserName, 0);
+                Log.LogWarning(exc.Message);
+                throw exc;
+            }
+
+            var newWorkspace = _repoWorkspace.NewWorkspace(workspace.Name, billingPlan,true, owner,GetCurrentUser());
+            _repoWorkspace.Commit();
+            return new ResultValueDto<WorkspaceRDto>(newWorkspace.Map<Workspace, WorkspaceRDto>());
+        }
+
+        public async Task<ResultsValueDto<WorkspaceRDto>> GetWorkspacesAsync(WorkspaceScopeEnums scope, PagingDto paging,string ownerUserName)
+        {
+            List<Workspace> workspaces = null;
+            switch (scope)
+            {
+                case WorkspaceScopeEnums.All:
+                    workspaces = _repoWorkspace.Query(paging).ToList();
+                    break;
+                case WorkspaceScopeEnums.Empty:
+                    workspaces = _repoWorkspace.GetAllEmpty(paging).ToList();
+                    break;
+                case WorkspaceScopeEnums.NotEmpty:
+                    workspaces = _repoWorkspace.GetAllNonEmpty(paging).ToList();
+                    break;
+                case WorkspaceScopeEnums.My:
+                    var owner = _repoUser.GetByName(ownerUserName);
+                    if (owner == null)
+                    {
+                        var exc = new EntityNotExistsException(typeof(User), ownerUserName, 0);
+                        Log.LogWarning(exc.Message);
+                        throw exc;
+                    }
+                    workspaces = _repoWorkspace.GetAllByOwner(owner, paging).ToList();
+                    break;
+            }
+
+            return new ResultsValueDto<WorkspaceRDto>(workspaces.MapList<Workspace, WorkspaceRDto>());
+        }
+
+        #endregion
+    }
+}

+ 19 - 0
AppServer/Connector.Console/Connection.cs

@@ -129,5 +129,24 @@ namespace BO.Connector.Console
         }
         #endregion
 
+
+        #region *** Workspace ***
+        public async Task<WorkspaceRDto> CreateWorkspaceAsync(WorkspaceCDto workspace)
+        {
+            CheckIsOpen();
+            var result = await CallRequestAsync<ResultValueDto<WorkspaceRDto>>($"{Ticket}/workspace", RestCallTypeEnum.Post,workspace);
+            return result.Value;
+        }
+
+        public async Task<IEnumerable<WorkspaceRDto>> GetWorkspacesAsync(WorkspaceScopeEnums scope,string userContext, PagingDto paging = null)
+        {
+            CheckIsOpen();
+            var headers = GetPagingHeaderAttributes(paging);
+            headers.Add("context", userContext);
+            var result = await CallRequestAsync<ResultsValueDto<WorkspaceRDto>>($"{Ticket}/workspaces/{scope}", RestCallTypeEnum.Get,null,headers);
+            return result.Values;
+        }
+        #endregion
+
     }
 }

+ 8 - 0
AppServer/Data/Repository/BillingPlanRepo.cs

@@ -1,4 +1,6 @@
+using System.Linq;
 using BO.AppServer.Data.Entity;
+using Quadarax.Foundation.Core.Data;
 using Quadarax.Foundation.Core.Data.Domain;
 using Quadarax.Foundation.Core.Data.Interface.Domain;
 using Quadarax.Foundation.Core.Data.Repository;
@@ -8,4 +10,10 @@ public class BillingPlanRepo : EntityRepository<long,  BillingPlan>
         public BillingPlanRepo(IUnitOfWork<DataDomain> unitOfWork) : base(unitOfWork)
         {
         }
+
+        
+        public BillingPlan GetByCode(string code)
+        {
+            return Query(new Paging()).FirstOrDefault(x => x.Code.ToUpper() == code.ToUpper());
+        }
     }

+ 4 - 0
AppServer/Data/Repository/UserRepo.cs

@@ -16,4 +16,8 @@ public class UserRepo : EntityRepository<long,  User>
             return Query(new Paging()).FirstOrDefault(x => x.Ifreference == ifReference);
         }
        
+        public User GetByName(string name)
+        {
+            return Query(new Paging()).FirstOrDefault(x => x.Name.ToLower() == name.ToLower());
+        }
     }

+ 41 - 0
AppServer/Data/Repository/WorkspaceRepo.cs

@@ -1,5 +1,10 @@
+using System;
+using System.Linq;
 using BO.AppServer.Data.Entity;
+using Microsoft.EntityFrameworkCore;
 using Quadarax.Foundation.Core.Data.Domain;
+using Quadarax.Foundation.Core.Data.Extensions;
+using Quadarax.Foundation.Core.Data.Interface;
 using Quadarax.Foundation.Core.Data.Interface.Domain;
 using Quadarax.Foundation.Core.Data.Repository;
 
@@ -8,4 +13,40 @@ public class WorkspaceRepo : EntityRepository<long,  Workspace>
         public WorkspaceRepo(IUnitOfWork<DataDomain> unitOfWork) : base(unitOfWork)
         {
         }
+
+        public Workspace NewWorkspace(string name, BillingPlan billingPlan, bool isDefault, User owner, User creator)
+        {
+            var workspace = New();
+            workspace.Created = DateTime.Now;
+            workspace.CreatedByUser = creator;
+            workspace.Structures.Add(new Structure(){Created = DateTime.Now,CreatedByUserId = creator.Id});
+            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);
+        }
+
+        public IQueryable<Workspace> GetAllEmpty(IPaging paging)
+        {
+            return Query(paging).Where(x => x.Structures.Any(struc => !struc.Metadocuments.Any()));
+        }
+        public IQueryable<Workspace> GetAllNonEmpty(IPaging paging)
+        {
+            return Query(paging).Where(x => x.Structures.Any(struc => struc.Metadocuments.Count>0));
+        }
+
+        public IQueryable<Workspace> GetAllByOwner(User owner, IPaging paging)
+        {
+            var userWorkspaceSet = Context.GetDbSet<DbSet<UserWorkspace>>();
+            return userWorkspaceSet.Page(paging.IsDisabled ? (int?)null : paging.Page, paging.PageSize)
+                .Where(x => x.User == owner).Select(x => x.Workspace);
+        }
     }

+ 7 - 6
AppServer/Metadata/Dto/WorkspaceDto.cs

@@ -4,21 +4,22 @@ using Quadarax.Foundation.Core.Data.Interface.Entity;
 
 namespace BO.AppServer.Metadata.Dto
 {
-    #region *** Workspace - Create ***
+    #region *** Workspace - Base ***
 
     public class WorkspaceBaseDto : BoDto
     {
         public string Name { get; set; }
         public string Apipassword { get; set; }
-        public long BillingPlanId { get; set; }
+        public string BillingPlanCode { get; set; }
     }
 
     #endregion
 
     #region *** Workspace - Create ***
 
-    internal class WorkspaceCDto : BoDto, ICreateDto
+    public class WorkspaceCDto : WorkspaceBaseDto, ICreateDto
     {
+        public string AssignedUserName { get; set; }
     }
 
     #endregion
@@ -27,6 +28,7 @@ namespace BO.AppServer.Metadata.Dto
 
     public class WorkspaceUDto : WorkspaceBaseDto, IUpdateDto
     {
+        public bool IsGold { get; set; }
     }
 
     #endregion
@@ -35,11 +37,10 @@ namespace BO.AppServer.Metadata.Dto
 
     public class WorkspaceRDto : WorkspaceBaseDto, IReadDto
     {
-        public IEnumerable<BillingInfoRDto> BillingInfos { get; set; }
-        public string BillingPlanCode { get; set; }
         public Guid Apikey { get; set; }
         public long CreditAmount { get; set; }
-
+        public IEnumerable<BillingInfoRDto> BillingInfos { get; set; }
+        public int DocumentsCount { get; set; }
         public BoAuditDto Audit { get; }
     }
 

+ 11 - 0
AppServer/Metadata/Enums/ScopeEnums.cs

@@ -60,6 +60,17 @@
         All,
     }
 
+    public enum WorkspaceScopeEnums
+    {
+        /// <summary>
+        /// Without limitations
+        /// </summary>
+        All,
+        Empty,
+        NotEmpty,
+        My
+    }
+
     public enum DocumentsScopeEnums
     {
         /// <summary>

+ 19 - 0
AppServer/Web/Services/ConsoleController.cs

@@ -20,15 +20,18 @@ namespace BO.AppServer.Web.Services
     {
         private UserService _srvUsers;
         private CatalogueService _srvCatalogue;
+        private WorkspaceService _srvWorkspace;
         protected override RoleEnum LoginRoleAllowed => RoleEnum.Console;
 
         public ConsoleController(UserService srvUsers, 
             CatalogueService srvCatalogue,
+            WorkspaceService srvWorkspace,
             ILoggerFactory logger,
             AccessService srvAccess) : base(logger, srvAccess)
         {
             _srvUsers = srvUsers ?? throw new ArgumentNullException(nameof(srvUsers));
             _srvCatalogue = srvCatalogue ?? throw new ArgumentNullException(nameof(srvCatalogue));
+            _srvWorkspace = srvWorkspace ?? throw new ArgumentNullException(nameof(srvWorkspace));
         }
         
         #region *** User ***
@@ -123,5 +126,21 @@ namespace BO.AppServer.Web.Services
         }
 
         #endregion
+
+        #region *** Workspace ***
+        [HttpGet("{Ticket}/workspace/{scope}")]
+        public async Task<ResultsValueDto<WorkspaceRDto>> GetAllWorkspaces(string ticket, WorkspaceScopeEnums scope, [FromHeader] string page, [FromHeader] string pageSize, [FromHeader] string context)
+        {
+            CheckAccess(ticket);
+            return await Call(async () => await _srvWorkspace.GetWorkspacesAsync(scope, new HeaderPagingDto(page, pageSize), context));
+        }
+
+        [HttpPost("{ticket}/workspace")]
+        public async Task<ResultValueDto<WorkspaceRDto>> CreateWorkspace(string ticket, [FromBody] WorkspaceCDto workspace)
+        {
+            CheckAccess(ticket);
+            return await Call(async () => await _srvWorkspace.CreateWorkspaceAsync(workspace));
+        }
+        #endregion
     }
 }

+ 2 - 0
AppServer/Web/Startup.cs

@@ -58,6 +58,7 @@ namespace AppServer
             services.AddScoped<UserService>();
             services.AddScoped<StatisticsService>();
             services.AddScoped<CatalogueService>();
+            services.AddScoped<WorkspaceService>();
 
             // Bo Repos
             services.AddScoped<DataDomain, BOContext>();
@@ -68,6 +69,7 @@ namespace AppServer
             services.AddScoped<BillingPlanRepo>();
             services.AddScoped<MimeTypeRepo>();
             services.AddScoped<StatisticRepo>();
+            services.AddScoped<WorkspaceRepo>();
 
 
             // Session framework

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

@@ -17,7 +17,7 @@ namespace Quadarax.Foundation.Core.Data.Repository
     {
         private IUnitOfWork<DataDomain> _unitOfWork;
         private DbSet<TEntity> DbSetInstance => _unitOfWork.Context.GetDbSet<DbSet<TEntity>>();
-
+        protected DataDomain Context => _unitOfWork.Context;
         
         protected EntityRepository(IUnitOfWork<DataDomain> unitOfWork)
         {

+ 44 - 0
Console/Commands/Workspace/WorkspaceAddCommand.cs

@@ -0,0 +1,44 @@
+using BO.AppServer.Metadata.Dto;
+using BO.Console.Commands.Base;
+using Quadarax.Foundation.Core.QConsole;
+using Quadarax.Foundation.Core.QConsole.Attributes;
+
+namespace BO.Console.Commands.Workspace
+{
+    [CommandDefinition]
+    internal class WorkspaceAddCommand : AbstractPostCommand<WorkspaceCDto, WorkspaceRDto>
+    {
+        #region *** Constants ***
+        private const string CS_CMD_WKSPADD_NAME = "workspace_add";
+        private const string CS_CMD_WKSPADD_DESCR = "Add new workspace/s assigned to user by import file.";
+
+        #endregion
+
+        #region *** Properties ***
+
+        public override string Name => CS_CMD_WKSPADD_NAME;
+        public override string Description => CS_CMD_WKSPADD_DESCR;
+
+        #endregion
+
+        #region *** Constructor ***
+        public WorkspaceAddCommand(Engine engine) : base(engine)
+        {
+        }
+        #endregion
+
+        #region *** EXECUTE ***
+        protected override  WorkspaceRDto IterationExecute(WorkspaceCDto data)
+        {
+            WriteDebugInfo($"Workspace '{data.Name}' for user '{data.AssignedUserName}' starts creating...");
+            var result = Client.CreateWorkspaceAsync(data).Result;
+            WriteCaption($"Workspace '{data.Name}' for user '{data.AssignedUserName}' created.");
+            return result;
+        }
+
+        #endregion
+
+        #region *** Private operations ***
+        #endregion
+    }
+}

+ 78 - 0
Console/Commands/Workspace/WorkspacesGetCommand.cs

@@ -0,0 +1,78 @@
+using System.Collections.Generic;
+using System.Linq;
+using BO.AppServer.Metadata.Enums;
+using BO.Console.Commands.Base;
+using Microsoft.VisualBasic;
+using Quadarax.Foundation.Core.QConsole;
+using Quadarax.Foundation.Core.QConsole.Argument;
+using Quadarax.Foundation.Core.QConsole.Attributes;
+using Quadarax.Foundation.Core.QConsole.Value;
+using Quadarax.Foundation.Core.Value;
+
+namespace BO.Console.Commands.Workspace
+{
+    [CommandDefinition]
+    internal class WorkspacesGetCommand : AbstractListScopedCommand<AppServer.Metadata.Enums.WorkspaceScopeEnums>
+    {
+        #region *** Constants ***
+
+        private const string CS_CMD_WRKSPGET_NAME = "workspace_list";
+        private const string CS_CMD_WRKSPGET_DESCR = "Get list of workspaces by specification scope.";
+
+
+        private const string CS_ARG_NAME_USER = "user";
+        private const string CS_ARG_HINT_USER = "<user_name>";
+        private const string CS_ARG_DESC_USER = "User name context when scope 'My' is selected. If not specified, use current user context.";
+
+        #endregion
+
+        #region *** Properties ***
+
+        public override string Name => CS_CMD_WRKSPGET_NAME;
+        public override string Description => CS_CMD_WRKSPGET_DESCR;
+
+        #endregion
+
+        #region *** Constructor ***
+
+        public WorkspacesGetCommand(Engine engine) : base(engine)
+        {
+        }
+
+        #endregion
+
+        #region *** EXECUTE ***
+
+        protected override Result OnExecute()
+        {
+            var workspaces = Client.GetWorkspacesAsync(Scope,GetArgumentValueOrDefault<string>(CS_ARG_NAME_USER), Paging).Result;
+            WriteDtoToConsole(workspaces,"Id","Name","Created","DocumentsCount", "ApiKey", "ApiPassword");
+            return new Result();
+        }
+
+        #endregion
+
+        #region *** Private operations ***
+
+        protected override void OnValidateArguments()
+        {
+            base.OnValidateArguments();
+            if (Scope != WorkspaceScopeEnums.My && WasArgumentSpecified(CS_ARG_NAME_USER))
+            {
+                WriteWarning($"Argument {Engine.Configuration.CharacterNamedArgumentSeparator}{CS_ARG_NAME_USER} is not allowed in scope '{Scope}'. Skipped.");
+                var arg = GetArgument(CS_ARG_NAME_USER);
+                arg.SetValueAsDefault();
+            }
+
+        }
+
+        protected override IEnumerable<AbstractArgument> OnSetupArguments()
+        {
+            var args = base.OnSetupArguments().ToList();
+            args.Add(new NamedArgument(CS_ARG_NAME_USER, CS_ARG_DESC_USER, CS_ARG_HINT_USER, TypeValuesEnum.String, string.Empty, false));
+            return args;
+        }
+
+        #endregion
+    }
+}

+ 13 - 0
Console/Samples/mimes.json

@@ -0,0 +1,13 @@
+[{
+"mimetype1":"text/plain",
+"description": "Plain text file",
+"extensions": "txt",
+"isenabled": true
+},
+{
+"mimetype1":"application/octet-stream",
+"description": "Binary file",
+"extensions": "bin",
+"isenabled": true
+}
+]

+ 9 - 0
Console/Samples/user_create_w_workspace.cmd

@@ -0,0 +1,9 @@
+REM ** Creates single user and creates own workspace structure **
+REM ** AppServer must be started first / this script must be run in same directory as BO.Console**
+REM ** MODIFY <user_name>, <user_password>, <user_email> before run! **
+
+echo [{"name":"<user_name>","password": "<user_password>","email": "<user_email>","langlcid": 1033,"roles":["User"]} > new_user.json
+echo [{"name":"<user_name>","apipassword": "<user_password>","billingplancode": "UNLIMITED","assignedusername": "<user_name>"}] > new_workspace.json
+
+BO.Console user_add -in:new_user.json
+BO.Console workspace_add -in:new_workspace.json

+ 8 - 0
Console/Samples/workspace.json

@@ -0,0 +1,8 @@
+[{
+"name":"workspace01",
+"apipassword": "ferda",
+"billingplancode": "UNLIMITED",
+"langlcid": 1033,
+"assignedusername": "ferda"
+}
+]