Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor create project #1305

Merged
merged 7 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 2 additions & 30 deletions backend/api/Controllers/ProjectsController.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
using api.Authorization;
using api.Dtos;
using api.Exceptions;
using api.Models;
using api.Models.Fusion;
using api.Services;
using api.Services.FusionIntegration;

using AutoMapper;

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web.Resource;

Expand All @@ -19,25 +12,19 @@ namespace api.Controllers;
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
public class ProjectsController : ControllerBase
{
private readonly IFusionService _fusionService;
private readonly IProjectService _projectService;
private readonly ICompareCasesService _compareCasesService;
private readonly ITechnicalInputService _technicalInputService;
private readonly IMapper _mapper;

public ProjectsController(
IProjectService projectService,
IFusionService fusionService,
ICompareCasesService compareCasesService,
ITechnicalInputService technicalInputService,
IMapper mapper
ITechnicalInputService technicalInputService
)
{
_projectService = projectService;
_fusionService = fusionService;
_compareCasesService = compareCasesService;
_technicalInputService = technicalInputService;
_mapper = mapper;
}

[RequiresApplicationRoles(
Expand All @@ -60,22 +47,7 @@ public async Task<ProjectWithAssetsDto> Get(Guid projectId)
[ActionType(ActionType.Edit)]
public async Task<ProjectWithAssetsDto> CreateProject([FromQuery] Guid contextId)
{
var projectMaster = await _fusionService.ProjectMasterAsync(contextId);
if (projectMaster != null)
{
var project = _mapper.Map<Project>(projectMaster);

if (project == null)
{
throw new ArgumentNullException(nameof(project));
}

project.CreateDate = DateTimeOffset.UtcNow;

return await _projectService.CreateProject(project);
}

return new ProjectWithAssetsDto();
return await _projectService.CreateProject(contextId);
}

[RequiresApplicationRoles(
Expand Down
8 changes: 8 additions & 0 deletions backend/api/Exceptions/ProjectAlreadyExistsException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace api.Exceptions;

public class ProjectAlreadyExistsException : Exception
{
public ProjectAlreadyExistsException(string message) : base(message)
{
}
}
15 changes: 5 additions & 10 deletions backend/api/FusionIntegration/FusionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public FusionService(
_logger = logger;
}

public async Task<FusionProjectMaster> ProjectMasterAsync(Guid contextId)
public async Task<FusionProjectMaster?> GetProjectMasterFromFusionContextId(Guid contextId)
{
var projectMasterContext = await ResolveProjectMasterContext(contextId);

Expand All @@ -28,22 +28,17 @@ public async Task<FusionProjectMaster> ProjectMasterAsync(Guid contextId)
{
// -> No, still not found. Then we log this and fail hard, as the callee should have provided with a
// valid ProjectMaster (context) ID.
Console.WriteLine(
"Could not resolve ProjectMaster context from Fusion using GUID '{ProjectMasterId}'" +
contextId);
throw new Exception();
_logger.LogInformation($"Could not resolve ProjectMaster context from Fusion using GUID '{{contextId}}'", contextId);
return null;
}

var serializedProjectMaster = JsonConvert.SerializeObject(projectMasterContext.Value);
FusionProjectMaster? fusionProjectMaster = JsonConvert.DeserializeObject<FusionProjectMaster>(serializedProjectMaster);

if (fusionProjectMaster == null)
{
Console.WriteLine(
"Project Master with ID '{ProjectMasterId}' was obtained from Fusion, but conversion to explicit " +
"type failed" +
contextId);
throw new Exception();
_logger.LogError("Project Master with ID '{contextId}' was obtained from Fusion, but conversion to explicit type failed", contextId);
return null;
}

return fusionProjectMaster;
Expand Down
2 changes: 1 addition & 1 deletion backend/api/FusionIntegration/IFusionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ public interface IFusionService
/// <param name="contextId">The projectMaster ID to query for.</param>
/// <returns>A <see cref="ProjectMaster"/> for the given id.</returns>
/// <exception cref="OperationFailed">If no projectMaster was found for the given ID.</exception>
public Task<FusionProjectMaster> ProjectMasterAsync(Guid contextId);
Task<FusionProjectMaster?> GetProjectMasterFromFusionContextId(Guid contextId);
}
55 changes: 55 additions & 0 deletions backend/api/Helpers/CommonLibraryHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using api.Models;

namespace api.Helpers
{
public static class CommonLibraryHelper
{
public static ProjectCategory ConvertCategory(string category)
{
return category switch
{
"" => ProjectCategory.Null,
"BROWNFIELD" => ProjectCategory.Brownfield,
"CESSATION" => ProjectCategory.Cessation,
"DRILLING_UPGRADE" => ProjectCategory.DrillingUpgrade,
"ONSHORE" => ProjectCategory.Onshore,
"PIPELINE" => ProjectCategory.Pipeline,
"PLATFORM_FPSO" => ProjectCategory.PlatformFpso,
"SUBSEA" => ProjectCategory.Subsea,
"SOLAR" => ProjectCategory.Solar,
"CO2 STORAGE" => ProjectCategory.Co2Storage,
"EFUEL" => ProjectCategory.Efuel,
"NUCLEAR" => ProjectCategory.Nuclear,
"CO2 CAPTURE" => ProjectCategory.Co2Capture,
"FPSO" => ProjectCategory.Fpso,
"HYDROGEN" => ProjectCategory.Hydrogen,
"HSE" => ProjectCategory.Hse,
"OFFSHORE_WIND" => ProjectCategory.OffshoreWind,
"PLATFORM" => ProjectCategory.Platform,
"POWER_FROM_SHORE" => ProjectCategory.PowerFromShore,
"TIE-IN" => ProjectCategory.TieIn,
"RENEWABLE_OTHER" => ProjectCategory.RenewableOther,
"CCS" => ProjectCategory.Ccs,
_ => throw new ArgumentException(string.Format("Category {0} does not exist in DCD.", category)),
};
}

public static ProjectPhase ConvertPhase(string phase)
{
return phase switch
{
"" => ProjectPhase.Null,
"Bid preparations" => ProjectPhase.BidPreparations,
"Business identification" => ProjectPhase.BusinessIdentification,
"Business planning" => ProjectPhase.BusinessPlanning,
"Concept planning" => ProjectPhase.ConceptPlanning,
"Concession / Negotiations" => ProjectPhase.ConcessionNegotiations,
"Definition" => ProjectPhase.Definition,
"Execution" => ProjectPhase.Execution,
"Operation" => ProjectPhase.Operation,
"Screening business opportunities" => ProjectPhase.ScreeningBusinessOpportunities,
_ => throw new ArgumentException(string.Format("Phase {0} does not exist in DCD.", phase)),
};
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace api.Helpers;
namespace api.Helpers.Prosp;

public class Prosp
{
Expand Down
25 changes: 15 additions & 10 deletions backend/api/Middleware/ExceptionHandlingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ public class ExceptionHandlingMiddleware
private readonly RequestDelegate _next;
private readonly ILogger _logger;

public ExceptionHandlingMiddleware(RequestDelegate requestDelegate, ILogger<ExceptionHandlingMiddleware> logger)
public ExceptionHandlingMiddleware(
RequestDelegate requestDelegate,
ILogger<ExceptionHandlingMiddleware> logger
)
{
_next = requestDelegate;
_logger = logger;
Expand Down Expand Up @@ -47,27 +50,29 @@ private Task HandleException(HttpContext context, Exception exception)

switch (exception)
{
case NotFoundInDBException _:
case KeyNotFoundException:
case NotFoundInDBException:
statusCode = HttpStatusCode.NotFound;
message = exception.Message;
break;
case UnauthorizedAccessException _:
case UnauthorizedAccessException:
statusCode = HttpStatusCode.Unauthorized;
message = exception.Message;
break;
case InvalidInputException _:
case WellChangeTypeException _:
case WellChangeTypeException:
case InvalidInputException:
statusCode = HttpStatusCode.BadRequest;
message = exception.Message;
break;
case ProjectAccessMismatchException _:
case ProjectClassificationException _:
case ProjectMembershipException _:
case ModifyRevisionException _:
case ProjectAccessMismatchException:
case ProjectClassificationException:
case ProjectMembershipException:
case ModifyRevisionException:
statusCode = HttpStatusCode.Forbidden;
message = exception.Message;
break;
case ResourceAlreadyExistsException _:
case ProjectAlreadyExistsException:
case ResourceAlreadyExistsException:
statusCode = HttpStatusCode.Conflict;
message = exception.Message;
break;
Expand Down
2 changes: 1 addition & 1 deletion backend/api/Models/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class Project
public string Name { get; set; } = string.Empty;
public bool IsRevision { get; set; }
public Guid CommonLibraryId { get; set; }
public Guid FusionProjectId { get; set; } // ExternalId?
public Guid FusionProjectId { get; set; } // ExternalId
public Guid ReferenceCaseId { get; set; }
public string CommonLibraryName { get; set; } = null!;
public string Description { get; set; } = string.Empty;
Expand Down
1 change: 1 addition & 0 deletions backend/api/Repositories/Project/IProjectRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public interface IProjectRepository : IBaseRepository
{
Task<Project?> GetProject(Guid projectId);
Task<Project?> GetProjectByIdOrExternalId(Guid id);
Task<Project?> GetProjectByExternalId(Guid id);
Task<Project?> GetProjectWithCases(Guid projectId);
Project UpdateProject(Project updatedProject);
Task<ExplorationOperationalWellCosts?> GetExplorationOperationalWellCosts(Guid id);
Expand Down
6 changes: 6 additions & 0 deletions backend/api/Repositories/Project/ProjectRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ ILogger<ProjectRepository> logger
.FirstOrDefaultAsync(p => p.Id == id || p.FusionProjectId == id);
}

public async Task<Project?> GetProjectByExternalId(Guid id)
{
return await _context.Projects
.FirstOrDefaultAsync(p => p.FusionProjectId == id);
}

public async Task<Project?> GetProjectWithCases(Guid projectId)
{
return await _context.Projects
Expand Down
2 changes: 1 addition & 1 deletion backend/api/Services/Entities/IProjectService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace api.Services;
public interface IProjectService
{
Task<ProjectWithCasesDto> UpdateProject(Guid projectId, UpdateProjectDto projectDto);
Task<ProjectWithAssetsDto> CreateProject(Project project);
Task<ProjectWithAssetsDto> CreateProject(Guid contextId);
Task<Project> GetProject(Guid projectId);
Task<Project> GetProjectWithoutAssets(Guid projectId);
Task<Project> GetProjectWithoutAssetsNoTracking(Guid projectId);
Expand Down
Loading