using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using Coscine.Api.Project.ReturnObjects; using Coscine.ApiCommons.Models; using Coscine.Database.Model; using LinqToDB; namespace Coscine.Api.Project.Models { public class ProjectModel : DatabaseModel { public ProjectModel() : base(Program.Configuration) { } public Coscine.Database.Model.Project StoreFromObject(ProjectObject projectObject, User user) { if(projectObject.Disciplines.Count() == 0 || projectObject.Institutes.Count() == 0) { throw new ArgumentException("Discipline and Institute are necessary!"); } Coscine.Database.Model.Project project = new Coscine.Database.Model.Project() { Description = projectObject.Description, DisplayName = projectObject.DisplayName, StartDate = projectObject.StartDate, EndDate = projectObject.EndDate, Keywords = projectObject.Keywords, ProjectName = projectObject.ProjectName, PrincipleInvestigators = projectObject.PrincipleInvestigators, GrantId = projectObject.GrantId, VisibilityId = projectObject.Visibility.Id, }; Insert(project); try { SetDisciplines(project, projectObject.Disciplines); SetInstitutes(project, projectObject.Institutes); } catch (Exception e) { Delete(project); throw e; } SetOwner(project, user); return project; } private void SetDisciplines(Database.Model.Project project, IEnumerable disciplines) { ProjectDisciplineModel projectDisciplineModel = new ProjectDisciplineModel(); foreach(var oldDiscipline in projectDisciplineModel.GetAllWhere((projectDiscipline) => projectDiscipline.ProjectId == project.Id)) { projectDisciplineModel.Delete(oldDiscipline); } foreach (var discipline in disciplines) { projectDisciplineModel.Insert(new ProjectDiscipline() { ProjectId = project.Id, DisciplineId = discipline.Id }); } } private void SetInstitutes(Database.Model.Project project, IEnumerable institutes) { ProjectInstituteModel projectInstituteModel = new ProjectInstituteModel(); foreach (var oldInstitute in projectInstituteModel.GetAllWhere((projectInstitute) => projectInstitute.ProjectId == project.Id)) { projectInstituteModel.Delete(oldInstitute); } foreach (var institute in institutes) { projectInstituteModel.Insert(new ProjectInstitute() { ProjectId = project.Id, InstituteId = institute.Id }); } } public ProjectRole SetOwner(Coscine.Database.Model.Project project, User user) { ProjectRoleModel projectRoleModel = new ProjectRoleModel(); ProjectRole projectRole = new ProjectRole() { RelationId = Guid.NewGuid(), ProjectId = project.Id, UserId = user.Id, RoleId = new RoleModel().GetWhere((x) => x.DisplayName == "Owner").Id }; projectRoleModel.Insert(projectRole); return projectRole; } public bool HasAccess(User user, Guid projectId, params string[] allowedAccess) { return HasAccess(user, GetById(projectId), allowedAccess); } public bool HasAccess(User user, Database.Model.Project project, params string[] allowedAccess) { ProjectRoleModel projectRoleModel = new ProjectRoleModel(); allowedAccess = allowedAccess.Select(x => x.ToLower().Trim()).ToArray(); IEnumerable projectRoles = projectRoleModel.GetAllWhere( (projectRoleRelation) => projectRoleRelation.ProjectId == project.Id && projectRoleRelation.UserId == user.Id && allowedAccess.Contains(projectRoleRelation.Role.DisplayName.ToLower())); return projectRoles.Count() > 0; } public IEnumerable GetWithAccess(User user, params string[] allowedAccess) { ProjectRoleModel projectRoleModel = new ProjectRoleModel(); ProjectModel projectModel = new ProjectModel(); allowedAccess = allowedAccess.Select(x => x.ToLower().Trim()).ToArray(); var allUserProjectRoles = projectRoleModel.GetAllWhere((projectRoleRelation) => projectRoleRelation.UserId == user.Id && allowedAccess.Contains(projectRoleRelation.Role.DisplayName.ToLower())); var allowedProjectIds = allUserProjectRoles.Select((projectRole) => projectRole.ProjectId); var allowedProjects = projectModel.GetAllWhere((project) => allowedProjectIds.Contains(project.Id) && ((!project.SubProjectsSubProjectIdIds.Any()) // get top level projects not having any parent projects || !(from subProject in project.SubProjectsSubProjectIdIds // check if the direct parent project is accessible to the current user where (from parentProjectRole in subProject.Project.ProjectRolesProjectIdIds where parentProjectRole.UserId == user.Id && allowedAccess.Contains(parentProjectRole.Role.DisplayName.ToLower()) select parentProjectRole).Any() select subProject).Any()) ); return allowedProjects.ToList(); } public void AddResource(Coscine.Database.Model.Project project, Resource resource) { ProjectResourceModel projectResourceModel = new ProjectResourceModel(); if (projectResourceModel.GetAllWhere((projectResource) => projectResource.ResourceId == resource.Id && projectResource.ProjectId == project.Id).Any()) { throw new InvalidOperationException("Resource is already assigned to project!"); } ProjectResource newProjectResource = new ProjectResource { ProjectId = project.Id, ResourceId = resource.Id }; projectResourceModel.Insert(newProjectResource); } public int UpdateByObject(Database.Model.Project project, ProjectObject projectObject) { if (projectObject.Disciplines.Count() == 0 || projectObject.Institutes.Count() == 0) { throw new ArgumentException("Discipline and Institute are necessary!"); } project.Description = projectObject.Description; project.DisplayName = projectObject.DisplayName; project.StartDate = projectObject.StartDate; project.EndDate = projectObject.EndDate; project.Keywords = projectObject.Keywords; project.ProjectName = projectObject.ProjectName; project.PrincipleInvestigators = projectObject.PrincipleInvestigators; project.GrantId = projectObject.GrantId; SetDisciplines(project, projectObject.Disciplines); SetInstitutes(project, projectObject.Institutes); project.VisibilityId = projectObject.Visibility.Id; return Update(project); } public ProjectObject CreateReturnObjectFromDatabaseObject(Database.Model.Project project) { return CreateReturnObjectFromDatabaseObject(project, new Guid()); } public ProjectObject CreateReturnObjectFromDatabaseObject(Database.Model.Project project, Guid parentId) { IEnumerable disciplines = new List(); if(project.ProjectDisciplineProjectIdIds == null) { DisciplineModel disciplineModel = new DisciplineModel(); disciplines = disciplineModel.GetAllWhere((discipline) => (from relation in discipline.ProjectDisciplineDisciplineIdIds where relation.ProjectId == project.Id select relation).Any()) .Select((discipline) => new DisciplineObject(discipline.Id, discipline.Url, discipline.DisplayNameDe, discipline.DisplayNameEn)); } else { disciplines = project.ProjectDisciplineProjectIdIds.Select((discipline) => new DisciplineObject(discipline.Discipline.Id, discipline.Discipline.Url, discipline.Discipline.DisplayNameDe, discipline.Discipline.DisplayNameEn)); } IEnumerable institutes = new List(); if (project.ProjectInstituteProjectIdIds == null) { InstituteModel instituteModel = new InstituteModel(); institutes = instituteModel.GetAllWhere((institute) => (from relation in institute.ProjectInstituteInstituteIdIds where relation.ProjectId == project.Id select relation).Any()) .Select((institute) => new InstituteObject(institute.Id, institute.IKZ, institute.DisplayName)); } else { institutes = project.ProjectInstituteProjectIdIds.Select((institute) => new InstituteObject(institute.Institute.Id, institute.Institute.IKZ, institute.Institute.DisplayName)); } if (project.Visibility == null && project.VisibilityId.HasValue) { VisibilityModel visibilityModel = new VisibilityModel(); project.Visibility = visibilityModel.GetById(project.VisibilityId.Value); } return new ProjectObject(project.Id, project.Description, project.DisplayName, project.StartDate, project.EndDate, project.Keywords, project.ProjectName, project.PrincipleInvestigators, project.GrantId, disciplines, institutes, project.Visibility == null ? null : new VisibilityObject(project.Visibility.Id, project.Visibility.DisplayName), parentId); } public override Expression> GetIdFromObject() { return databaseObject => databaseObject.Id; } public override ITable GetITableFromDatabase(CoscineDB db) { return db.Projects; } public override void SetObjectId(Database.Model.Project databaseObject, Guid id) { databaseObject.Id = id; } } }