Skip to content

Commit

Permalink
[SPDBT-3414][SPDBT-3415]Licensing-be: Add an endpoint in licenceContr…
Browse files Browse the repository at this point in the history
…oller to accept request with licencenumber, fn and ln. (#1973)

# Description

This PR includes the following proposed change(s):

- [SPDBT-3414] Licensing-be: Add an endpoint in licenceController to
accept request with licencenumber, fn and ln.
- [SPDBT-3415] License-be: provide an endpoint for searching biz
licence.
  • Loading branch information
peggy-quartech authored Dec 6, 2024
1 parent 64bc06a commit f757e30
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/Spd.Manager.Licence/LicenceContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public interface ILicenceManager
public Task<LicenceResponse> Handle(LicenceByIdQuery query, CancellationToken ct);
public Task<LicenceResponse> Handle(LicenceQuery query, CancellationToken ct);
public Task<IEnumerable<LicenceBasicResponse>> Handle(LicenceListQuery query, CancellationToken ct);
public Task<IEnumerable<LicenceBasicResponse>> Handle(LicenceListSearch search, CancellationToken ct);
public Task<FileResponse> Handle(LicencePhotoQuery query, CancellationToken ct);
}

Expand Down Expand Up @@ -65,3 +66,4 @@ public record LicenceQuery(string? LicenceNumber, string? AccessCode) : IRequest
public record LicenceByIdQuery(Guid LicenceId) : IRequest<LicenceResponse>;
public record LicenceListQuery(Guid? ApplicantId, Guid? BizId) : IRequest<IEnumerable<LicenceBasicResponse>>;
public record LicencePhotoQuery(Guid LicenceId) : IRequest<FileResponse>;
public record LicenceListSearch(string? LicenceNumber, string? FirstName, string? LastName, string? BizName, ServiceTypeCode ServiceTypeCode) : IRequest<IEnumerable<LicenceBasicResponse>>;
53 changes: 52 additions & 1 deletion src/Spd.Manager.Licence/LicenceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ internal class LicenceManager :
IRequestHandler<LicenceQuery, LicenceResponse>,
IRequestHandler<LicencePhotoQuery, FileResponse>,
IRequestHandler<LicenceListQuery, IEnumerable<LicenceBasicResponse>>,
IRequestHandler<LicenceListSearch, IEnumerable<LicenceBasicResponse>>,
ILicenceManager
{
private readonly ILicenceRepository _licenceRepository;
Expand Down Expand Up @@ -100,7 +101,7 @@ public async Task<IEnumerable<LicenceBasicResponse>> Handle(LicenceListQuery que
if (!response.Items.Any())
{
_logger.LogDebug("No licence found.");
return Array.Empty<LicenceResponse>();
return Array.Empty<LicenceBasicResponse>();
}

//only return expired and active ones
Expand Down Expand Up @@ -145,6 +146,55 @@ public async Task<IEnumerable<LicenceBasicResponse>> Handle(LicenceListQuery que
return new FileResponse();
}

public async Task<IEnumerable<LicenceBasicResponse>> Handle(LicenceListSearch search, CancellationToken cancellationToken)
{
LicenceListResp response = new LicenceListResp();
if (search.ServiceTypeCode == ServiceTypeCode.SecurityWorkerLicence)
{
if (string.IsNullOrWhiteSpace(search.LicenceNumber) && string.IsNullOrWhiteSpace(search.FirstName) && string.IsNullOrWhiteSpace(search.LastName))
throw new ApiException(HttpStatusCode.BadRequest, "Not enough parameter");
if ((!string.IsNullOrWhiteSpace(search.LicenceNumber) && !string.IsNullOrWhiteSpace(search.FirstName))
|| (!string.IsNullOrWhiteSpace(search.LicenceNumber) && !string.IsNullOrWhiteSpace(search.LastName)))
throw new ApiException(HttpStatusCode.BadRequest, "Cannot search name and licence number together.");
response = await _licenceRepository.QueryAsync(
new LicenceQry
{
LicenceNumber = search.LicenceNumber,
FirstName = search.FirstName,
LastName = search.LastName,
Type = ServiceTypeEnum.SecurityWorkerLicence,
IncludeInactive = true
}, cancellationToken);
}

if (search.ServiceTypeCode == ServiceTypeCode.SecurityBusinessLicence)
{
if (string.IsNullOrWhiteSpace(search.LicenceNumber) && string.IsNullOrWhiteSpace(search.BizName))
throw new ApiException(HttpStatusCode.BadRequest, "Not enough parameter");
if (!string.IsNullOrWhiteSpace(search.LicenceNumber) && !string.IsNullOrWhiteSpace(search.BizName))
throw new ApiException(HttpStatusCode.BadRequest, "Cannot search biz name and licence number together.");
if (!string.IsNullOrWhiteSpace(search.BizName) && search.BizName.Length < 3)
throw new ApiException(HttpStatusCode.BadRequest, "Business name must have at least 3 chars.");

response = await _licenceRepository.QueryAsync(
new LicenceQry
{
LicenceNumber = search.LicenceNumber,
BizName = search.BizName,
IncludeInactive = true,
Type = ServiceTypeEnum.SecurityBusinessLicence,
}, cancellationToken);
}

var result = response.Items.Where(r => r.LicenceStatusCode == LicenceStatusEnum.Active || r.LicenceStatusCode == LicenceStatusEnum.Expired || r.LicenceStatusCode == LicenceStatusEnum.Preview)
.GroupBy(r => r.LicenceNumber)
.Select(g => g.OrderByDescending(i => i.CreatedOn).FirstOrDefault())
.ToList();
//only return expired and active ones
return _mapper.Map<IEnumerable<LicenceBasicResponse>>(result);

}

private async Task GetSoleProprietorInfoAsync(LicenceResponse lic, LicenceResp licResp, CancellationToken cancellationToken)
{
if (licResp.ServiceTypeCode == ServiceTypeEnum.SecurityWorkerLicence && licResp.SoleProprietorOrgId != null)
Expand Down Expand Up @@ -217,4 +267,5 @@ private async Task GetDogRestraintsDocumentsInfoAsync(LicenceResponse lic, Cance
lic.RestraintsDocumentInfos = _mapper.Map<IEnumerable<Document>>(docList.Items);
}
}

}
25 changes: 25 additions & 0 deletions src/Spd.Presentation.Licensing/Controllers/LicenceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,30 @@ public async Task<LicenceResponse> GetLicence([FromRoute] Guid licenceId, Cancel
{
return await _mediator.Send(new LicenceByIdQuery(licenceId), ct);
}

/// <summary>
/// Get latest secure worker licence by licence number or firstname, lastname
/// Example: http://localhost:5114/api/licences/security-worker-licence?licenceNumber=E123
/// http://localhost:5114/api/licences/security-worker-licence?firstName=XXX&lastName=yyy
/// </summary>
[Route("api/licences/security-worker-licence")]
[HttpGet]
[AllowAnonymous]
public async Task<IEnumerable<LicenceBasicResponse>> SearchSecureWorkerLicence([FromQuery] string? licenceNumber, [FromQuery] string? firstName = null, [FromQuery] string? lastName = null)
{
return await _mediator.Send(new LicenceListSearch(licenceNumber?.Trim(), firstName?.Trim(), lastName?.Trim(), null, ServiceTypeCode.SecurityWorkerLicence));
}

/// <summary>
/// Get latest secure business licence by licence number or at least the first 3 letters of biz name (for either legal name or trade name)
/// Example: http://localhost:5114/api/licences/business-licence?licenceNumber=B123
/// </summary>
[Route("api/licences/business-licence")]
[HttpGet]
[AllowAnonymous]
public async Task<IEnumerable<LicenceBasicResponse>> SearchBizLicence([FromQuery] string? licenceNumber, [FromQuery] string? businessName = null)
{
return await _mediator.Send(new LicenceListSearch(licenceNumber, null, null, businessName, ServiceTypeCode.SecurityBusinessLicence));
}
}
}
3 changes: 3 additions & 0 deletions src/Spd.Resource.Repository/Licence/Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ public record LicenceQry
public ServiceTypeEnum? Type { get; set; }
public bool IncludeInactive { get; set; }
public bool? IsExpired { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? BizName { get; set; }
};
public record LicenceListResp
{
Expand Down
14 changes: 8 additions & 6 deletions src/Spd.Resource.Repository/Licence/LicenceRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ public LicenceRepository(IDynamicsContextFactory ctx,

public async Task<LicenceListResp> QueryAsync(LicenceQry qry, CancellationToken ct)
{
if (qry.LicenceNumber == null && qry.AccountId == null && qry.ContactId == null && qry.LicenceId == null)
{
throw new ArgumentException("at least need 1 parameter to do licence query.");
}

IQueryable<spd_licence> lics = _context.spd_licences
.Expand(i => i.spd_spd_licence_spd_caselicencecategory_licenceid)
.Expand(i => i.spd_LicenceHolder_contact)
Expand Down Expand Up @@ -90,7 +85,14 @@ public async Task<LicenceListResp> QueryAsync(LicenceQry qry, CancellationToken
{
lics = lics.Where(a => a.spd_LicenceHolder_contact.spd_accesscode == qry.AccessCode);
}

if (qry.LastName != null || qry.FirstName != null)
{
lics = lics.Where(a => a.spd_LicenceHolder_contact.firstname == qry.FirstName && a.spd_LicenceHolder_contact.lastname == qry.LastName);
}
if (qry.BizName != null)
{
lics = lics.Where(a => a.spd_LicenceHolder_account.name.StartsWith(qry.BizName) || a.spd_LicenceHolder_account.spd_organizationlegalname.StartsWith(qry.BizName));
}
return new LicenceListResp()
{
Items = _mapper.Map<IEnumerable<LicenceResp>>(lics)
Expand Down

0 comments on commit f757e30

Please sign in to comment.