Skip to content
Snippets Groups Projects

Update: KPI generator for Project

Merged Sirieam Marie Hunke requested to merge Issue/2184-kpiGeneratorProject into dev
Files
3
using KPIGenerator.Utils;
using Coscine.Database.DataModel;
using Coscine.Database.Models;
using Coscine.Database.ReturnObjects;
using Coscine.ResourceTypes;
using KPIGenerator.Utils;
using Newtonsoft.Json;
using static KPIGenerator.Utils.CommandLineOptions;
namespace KPIGenerator.Reportings.Project;
public class ProjectReporting : Reporting<ProjectReportingOptions>
{
private readonly ProjectModel _projectModel;
private readonly ResourceModel _resourceModel;
private readonly ProjectRoleModel _projectRoleModel;
private readonly ProjectQuotaModel _projectQuotaModel;
private readonly ResourceTypeModel _resourceTypeModel;
public ProjectReporting(ProjectReportingOptions options) : base(options)
{
ReportingFileName = "projects.json";
_projectModel = new ProjectModel();
_projectRoleModel = new ProjectRoleModel();
_projectQuotaModel = new ProjectQuotaModel();
_resourceModel = new ResourceModel();
_resourceTypeModel = new ResourceTypeModel();
}
public override IEnumerable<ReportingFileObject> GenerateReporting()
{
/*
* 1. Collect the reporting for the whole database -- General/{ReportingReportingFileName}
* 2. Append to the list the same information per organization as folders -- Organizations/{OrgRorId}/{ReportingReportingFileName}
* --> See envisioned folder structure.
*/
throw new NotImplementedException();
var projects = _projectModel.GetAllWhere(r => r.Deleted.Equals(true) || r.Deleted.Equals(false));
var reportingFiles = new List<ReportingFileObject>();
var returnObjects = Generate(projects);
//General File
reportingFiles.Add(new ReportingFileObject
{
Path = GetReportingPathGeneral(ReportingFileName),
Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjects, Formatting.Indented)),
});
// Per Organization
reportingFiles.AddRange(GeneratePerOrganization(returnObjects));
return reportingFiles;
}
private List<ReturnObject> Generate(IEnumerable<Coscine.Database.DataModel.Project> projects)
{
var returnObjects = new List<ReturnObject>();
foreach (var project in projects)
{
var projectReturnObject = _projectModel.CreateReturnObjectFromDatabaseObject(project);
var projectReportEntry = new ReturnObject
{
Id = projectReturnObject.Id,
DateCreated = projectReturnObject.DateCreated,
Organizations = GetOrganizations(projectReturnObject),
Disciplines = projectReturnObject.Disciplines.ToList(),
Deleted = projectReturnObject.Deleted,
ProjectVisibilityId = projectReturnObject.Visibility.Id,
GrantId = projectReturnObject.GrantId,
Users = _projectRoleModel.GetAllWhere(x => x.ProjectId == projectReturnObject.Id).Count(),
ResourceTypeQuota = GetResourceTypeQuota(projectReturnObject.Id)
};
returnObjects.Add(projectReportEntry);
}
return returnObjects;
}
private IEnumerable<ReportingFileObject> GeneratePerOrganization(List<ReturnObject> returnObjects)
{
var reportingFilesPerOrganization = new List<ReportingFileObject>();
var organizationsFromProjects = returnObjects.SelectMany(ro => ro.Organizations).DistinctBy(o => o.RorUrl);
foreach (var entry in organizationsFromProjects)
{
var organization = Organizations.Find(o => o.Equals(entry));
if (organization is null)
{
organization = _otherOrganization;
Console.WriteLine($"WARNING!: Organization \"{entry.RorUrl}\" could not be correctly identified. Will use \"{_otherOrganization.RorUrl}\".");
}
var returnObjectsForOrganization = returnObjects.Where(ro => ro.Organizations.Select(o => o.RorUrl).Any(e => e.Equals(entry.RorUrl)));
reportingFilesPerOrganization.Add(new ReportingFileObject
{
Path = GetReportingPathOrganization(organization.RorUrl.Replace("https://ror.org/", "").ToLower(), ReportingFileName),
Content = ConvertStringContentsToStream(JsonConvert.SerializeObject(returnObjectsForOrganization, Formatting.Indented))
});
}
return reportingFilesPerOrganization;
}
private List<ResourceTypeQuotaReturnObject> GetResourceTypeQuota(Guid projectId)
{
var result = new List<ResourceTypeQuotaReturnObject>();
var types = ResourceTypeFactory.Instance.GetResourceTypes();
var resourceTypes = _resourceTypeModel.GetAllWhere(x => types.Any(t => x.SpecificType.Equals(t)));
var quotas = _projectQuotaModel.GetAllWhere(x => x.ProjectId == projectId);
var resourceQuotas = quotas.Where(x => resourceTypes.Any(e => x.ResourceTypeId.Equals(e.Id)));
result.AddRange(resourceQuotas.Select(x => CreateQuotaReturnObject(x, projectId)).ToList());
return result;
}
private ResourceTypeQuotaReturnObject CreateQuotaReturnObject(ProjectQuota projectQuota, Guid projectId)
{
return new ResourceTypeQuotaReturnObject
{
ResourceType = _resourceTypeModel.GetById(projectQuota.ResourceTypeId).SpecificType,
Allocated = new QuotaDimObject()
{
Value = projectQuota.Quota,
Unit = QuotaUnit.GibiBYTE,
},
Maximum = new QuotaDimObject()
{
Value = projectQuota.MaxQuota,
Unit = QuotaUnit.GibiBYTE,
},
TotalReserved = new QuotaDimObject()
{
Value = CalculateAllocatedForAll(_resourceTypeModel.GetById(projectQuota.ResourceTypeId), projectId),
Unit = QuotaUnit.GibiBYTE,
},
TotalUsed = new QuotaDimObject()
{
Value = CalculateUsedForAll(_resourceTypeModel.GetById(projectQuota.ResourceTypeId), projectId),
Unit = QuotaUnit.BYTE,
},
};
}
private int CalculateUsedForAll(ResourceType resourceType, Guid projectId)
{
var resources = _resourceModel.GetAllWhere((resource) =>
(from projectResource in resource.ProjectResources
where projectResource.ProjectId == projectId
select projectResource).Any() &&
resource.TypeId == resourceType.Id);
var used = resources.Sum(resource =>
{
// Linked has no quota.
var rt = ResourceTypeFactory.Instance.GetResourceType(resource);
if (rt.GetResourceTypeInformation().Result.IsQuotaAvailable)
{
return rt.GetResourceQuotaUsed(resource.Id.ToString(), _resourceModel.GetResourceTypeOptions(resource.Id)).Result;
}
else
{
return 0;
}
}
);
return (int)used;
}
private int CalculateAllocatedForAll(ResourceType resourceType, Guid projectId)
{
var resources = _resourceModel.GetAllWhere((resource) =>
(from projectResource in resource.ProjectResources
where projectResource.ProjectId == projectId
select projectResource).Any() &&
resource.TypeId == resourceType.Id);
var allocated = resources.Sum(resource =>
{
// Linked has no quota.
var rt = ResourceTypeFactory.Instance.GetResourceType(resource);
if (rt.GetResourceTypeInformation().Result.IsQuotaAvailable)
{
return rt.GetResourceQuotaAvailable(resource.Id.ToString(), _resourceModel.GetResourceTypeOptions(resource.Id)).Result;
}
else
{
return 0;
}
});
return (int)allocated;
}
private List<Organization> GetOrganizations(ProjectObject project)
{
var result = new List<Organization>();
foreach (var entry in project.Organizations)
{
result.Add(FetchOrganizationByRor(entry.Url));
}
return result;
}
}
}
\ No newline at end of file
Loading