Skip to content

Commit

Permalink
Merge pull request #684 from bcgov/yj
Browse files Browse the repository at this point in the history
feat(dss-361)
  • Loading branch information
ychung-mot authored Sep 27, 2024
2 parents ce4449d + a424757 commit acfccf7
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 101 deletions.
18 changes: 16 additions & 2 deletions server/StrDss.Api/Controllers/OrganizationsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ public async Task<ActionResult<StrRequirementsDto>> GetStrRequirements(double lo
}


[ApiAuthorize()]
[ApiAuthorize]
[HttpGet("platforms")]
public async Task<ActionResult<List<PlatformViewDto>>> GetPlatforms(int pageSize = 10, int pageNumber = 1, string orderBy = "OrganizationNm", string direction = "asc")
{
var platforms = await _orgService.GetPlatforms(pageSize, pageNumber, orderBy, direction);
return Ok(platforms);
}

[ApiAuthorize()]
[ApiAuthorize]
[HttpGet("platforms/{id}")]
public async Task<ActionResult<PlatformViewDto>> GetPlatform(long id)
{
Expand All @@ -100,5 +100,19 @@ public async Task<ActionResult<PlatformViewDto>> GetPlatform(long id)

return Ok(platform);
}

[ApiAuthorize(Permissions.UserWrite)] //todo: use platform_write permission when it's ready in the database
[HttpPost("platforms", Name = "CreatePlatform")]
public async Task<ActionResult> CreatePlatform(PlatformUpdateDto dto)
{
var (errors, id) = await _orgService.CreatePlatformAsync(dto);

if (errors.Any())
{
return ValidationUtils.GetValidationErrorResult(errors, ControllerContext);
}

return Ok(id);
}
}
}
85 changes: 11 additions & 74 deletions server/StrDss.Api/SwaggerDocumentFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,98 +7,35 @@ public class SwaggerDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var filteredPaths = new OpenApiPaths();
// Key is read-only so make a copy of the Paths property
var pathsPerConsumer = new OpenApiPaths();
var referencedSchemas = new HashSet<string>();

if (swaggerDoc.Info.Version == Common.ApiTags.Aps)
{
foreach (var path in swaggerDoc.Paths)
{
var operation = path.Value?.Operations?.Values?.FirstOrDefault();

if (operation != null && operation.Tags.Any(t => Common.ApiTags.ApsTagList.Contains(t.Name)))
// If there are any tags (all methods are decorated with "SwaggerOperation(Tags = new[]...") with the current consumer name
var p = path.Value?.Operations?.Values?.FirstOrDefault();
if (p != null && p.Tags
.Where(t => Common.ApiTags.ApsTagList.Contains(t.Name)).Any())
{
filteredPaths.Add(path.Key.ToLowerInvariant(), path.Value);
TrackSchemasInOperations(operation, referencedSchemas);
// Add the path to the collection of paths for current consumer
pathsPerConsumer.Add(path.Key, path.Value);
}
}

//swaggerDoc.Servers = new List<OpenApiServer>
//{
// new OpenApiServer { Url = "https://strdata.dev.api.gov.bc.ca" }
//};

}
else
{
foreach (var path in swaggerDoc.Paths)
{
if (path.Key != null && path.Value != null)
{
filteredPaths.Add(path.Key, path.Value);

foreach (var operation in path.Value.Operations.Values)
{
TrackSchemasInOperations(operation, referencedSchemas);
}
}
}
}

swaggerDoc.Paths = filteredPaths;

// Filter schemas in components to only include those that are referenced
var filteredSchemas = new Dictionary<string, OpenApiSchema>();
foreach (var schemaKey in swaggerDoc.Components.Schemas.Keys)
{
if (referencedSchemas.Contains(schemaKey))
{
filteredSchemas.Add(schemaKey, swaggerDoc.Components.Schemas[schemaKey]);
}
}

// Update the document's components with filtered schemas
swaggerDoc.Components.Schemas = filteredSchemas;
}

/// <summary>
/// Tracks the schemas used in the operation's parameters, request bodies, and responses.
/// </summary>
private void TrackSchemasInOperations(OpenApiOperation operation, HashSet<string> referencedSchemas)
{
// Track schemas from parameters
foreach (var parameter in operation.Parameters)
{
if (parameter.Schema?.Reference != null)
{
referencedSchemas.Add(parameter.Schema.Reference.Id);
}
}

// Track schemas from request bodies
if (operation.RequestBody?.Content != null)
{
foreach (var content in operation.RequestBody.Content.Values)
{
if (content.Schema?.Reference != null)
{
referencedSchemas.Add(content.Schema.Reference.Id);
}
if (path.Key != null && path.Value != null) pathsPerConsumer.Add(path.Key, path.Value);
}
}

// Track schemas from responses
foreach (var response in operation.Responses.Values)
{
foreach (var content in response.Content.Values)
{
if (content.Schema?.Reference != null)
{
referencedSchemas.Add(content.Schema.Reference.Id);
}
}
}
swaggerDoc.Paths = pathsPerConsumer;
}


}
}
22 changes: 11 additions & 11 deletions server/StrDss.Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,16 @@ public static class Entities
public const string RentalListingRowUntyped = "RentalListingRowUntyped";
public const string Role = "Role";
public const string BizLicenceRowUntyped = "BizLicenceRowUntyped";
public const string Platform = "Platform";

}
public static class Fields
{
public const string StreetAddress = "StreetAddress";
public const string City = "City";
public const string Province = "Province";
public const string PostalCode = "PostalCode";
public const string ZoningTypeId = "ZoningTypeId";
public const string SquareFootage = "SquareFootage";
public const string StrAffiliateId = "StrAffiliateId";
public const string IsOwnerPrimaryResidence = "IsOwnerPrimaryResidence";
public const string ComplianceStatusId = "ComplianceStatusId";

public const string Username = "Username";
public const string Passwrod = "Passwrod";
public const string LastName = "LastName";
public const string PhoneNumber = "PhoneNumber";
public const string RoleId = "RoleId";

}

public static class RentalListingReportFields
Expand Down Expand Up @@ -117,6 +107,16 @@ public static class BizLicenceRowFields
public const string PropertyLegalDescriptionTxt = "PropertyLegalDescriptionTxt";
}

public static class PlatformFields
{
public const string OrganizationId = "OrganizationId";
public const string OrganizationCd = "OrganizationCd";
public const string OrganizationNm = "OrganizationNm";
public const string NoticeOfTakedownContactEmail1 = "NoticeOfTakedownContactEmail1";
public const string TakedownRequestContactEmail1 = "TakedownRequestContactEmail1";
public const string NoticeOfTakedownContactEmail2 = "NoticeOfTakedownContactEmail2";
public const string TakedownRequestContactEmail2 = "TakedownRequestContactEmail2";
}

public static class RentalListingExport
{
Expand Down
2 changes: 1 addition & 1 deletion server/StrDss.Data/Mappings/EntityToModelProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public EntityToModelProfile()
.ForMember(o => o.UpdDtm, opt => opt.MapFrom(i => DateUtils.ConvertUtcToPacificTime(i.UpdDtm)));

CreateMap<DssBusinessLicence, BizLicenceSearchDto>();
CreateMap<DssOrganization, PlatformCreateDto>();
CreateMap<DssOrganization, PlatformUpdateDto>();
CreateMap<DssPlatformVw, PlatformViewDto>();
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/StrDss.Data/Mappings/ModelToEntityProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ModelToEntityProfile()
.ForMember(dest => dest.SeparateReservationsQty, opt => opt.MapFrom(src => CommonUtils.StringToShort(src.ReservationsQty)));

CreateMap<RoleUpdateDto, DssUserRole>();
CreateMap<PlatformCreateDto, DssOrganization>();
CreateMap<PlatformUpdateDto, DssOrganization>();
}
}
}
36 changes: 36 additions & 0 deletions server/StrDss.Data/Repositories/OrganizationRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using StrDss.Model;
using StrDss.Model.OrganizationDtos;
using StrDss.Model.RentalReportDtos;
using System.Data;

namespace StrDss.Data.Repositories
{
Expand All @@ -25,6 +26,8 @@ public interface IOrganizationRepository
Task<StrRequirementsDto?> GetStrRequirements(double longitude, double latitude);
Task<PagedDto<PlatformViewDto>> GetPlatforms(int pageSize, int pageNumber, string orderBy, string direction);
Task<PlatformViewDto?> GetPlatform(long id);
Task<DssOrganization> CreatePlatformAsync(PlatformUpdateDto dto);
Task<bool> DoesOrgCdExist(string orgCd);
}
public class OrganizationRepository : RepositoryBase<DssOrganization>, IOrganizationRepository
{
Expand Down Expand Up @@ -175,5 +178,38 @@ public async Task<PagedDto<PlatformViewDto>> GetPlatforms(int pageSize, int page
return platform;
}

public async Task<DssOrganization> CreatePlatformAsync(PlatformUpdateDto dto)
{
var entity = _mapper.Map<DssOrganization>(dto);

entity.OrganizationType = OrganizationTypes.Platform;

await _dbSet.AddAsync(entity);

CreateContact(entity, EmailMessageTypes.NoticeOfTakedown, dto.NoticeOfTakedownContactEmail1, true);
CreateContact(entity, EmailMessageTypes.NoticeOfTakedown, dto.NoticeOfTakedownContactEmail2, false);
CreateContact(entity, EmailMessageTypes.TakedownRequest, dto.TakedownRequestContactEmail1, true);
CreateContact(entity, EmailMessageTypes.TakedownRequest, dto.TakedownRequestContactEmail2, false);

return entity;
}

private void CreateContact(DssOrganization entity, string messageType, string? emailAddress, bool isPrimary)
{
if (!string.IsNullOrEmpty(emailAddress))
{
entity.DssOrganizationContactPeople.Add(new DssOrganizationContactPerson
{
EmailAddressDsc = emailAddress,
IsPrimary = isPrimary,
EmailMessageType = messageType
});
}
}

public async Task<bool> DoesOrgCdExist(string orgCd)
{
return await _dbSet.AnyAsync(x => x.OrganizationCd == orgCd);
}
}
}
12 changes: 0 additions & 12 deletions server/StrDss.Model/OrganizationDtos/PlatformCreateDto.cs

This file was deleted.

14 changes: 14 additions & 0 deletions server/StrDss.Model/OrganizationDtos/PlatformUpdateDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace StrDss.Model.OrganizationDtos
{
public class PlatformUpdateDto
{
public long OrganizationId { get; set; }
public string OrganizationCd { get; set; } = null!;
public string OrganizationNm { get; set; } = null!;
public DateTime UpdDtm { get; set; }
public string? NoticeOfTakedownContactEmail1 { get; set; }
public string? TakedownRequestContactEmail1 { get; set; }
public string? NoticeOfTakedownContactEmail2 { get; set; }
public string? TakedownRequestContactEmail2 { get; set; }
}
}
1 change: 1 addition & 0 deletions server/StrDss.Service/FieldValidatorService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public FieldValidatorService()
RentalListingReportValidationRule.LoadReportValidationRules(_rules);
RoleValidationRule.LoadReportValidationRules(_rules);
BizLicenceValidationRule.LoadBizLicenceValidationRules(_rules);
PlatformValidationRule.LoadPlatformUpdateValidationRules(_rules);
}

public IEnumerable<FieldValidationRule> GetFieldValidationRules(string entityName)
Expand Down
38 changes: 38 additions & 0 deletions server/StrDss.Service/OrganizationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using StrDss.Data.Repositories;
using StrDss.Model;
using StrDss.Model.OrganizationDtos;
using StrDss.Model.UserDtos;
using System.Threading.Tasks;

namespace StrDss.Service
{
Expand All @@ -20,6 +22,7 @@ public interface IOrganizationService
Task<StrRequirementsDto?> GetStrRequirements(double longitude, double latitude);
Task<PagedDto<PlatformViewDto>> GetPlatforms(int pageSize, int pageNumber, string orderBy, string direction);
Task<PlatformViewDto?> GetPlatform(long id);
Task<(Dictionary<string, List<string>>, long)> CreatePlatformAsync(PlatformUpdateDto dto);
}
public class OrganizationService : ServiceBase, IOrganizationService
{
Expand Down Expand Up @@ -71,5 +74,40 @@ public async Task<PagedDto<PlatformViewDto>> GetPlatforms(int pageSize, int page
{
return await _orgRepo.GetPlatform(id);
}

public async Task<(Dictionary<string, List<string>>, long)> CreatePlatformAsync(PlatformUpdateDto dto)
{
var errors = new Dictionary<string, List<string>>();

await ValidatePlatformUpdateDto(dto, errors);

if (errors.Any())
{
return (errors, 0);
}

var entity = await _orgRepo.CreatePlatformAsync(dto);

_unitOfWork.Commit();

return (errors, entity.OrganizationId);
}

private async Task<Dictionary<string, List<string>>> ValidatePlatformUpdateDto(PlatformUpdateDto dto, Dictionary<string, List<string>> errors)
{
_validator.Validate(Entities.Platform, dto, errors);

if (errors.Any())
{
return errors;
}

if (await _orgRepo.DoesOrgCdExist(dto.OrganizationCd))
{
errors.AddItem("OrganizationCd", $"Organization Code {dto.OrganizationCd} already exists");
}

return errors;
}
}
}
Loading

0 comments on commit acfccf7

Please sign in to comment.