Skip to content

Commit 576c6dd

Browse files
authored
Merge pull request #893 from bcgov/feature/registration-validation
Feature/registration validation
2 parents fd161b0 + d27cbe7 commit 576c6dd

File tree

6 files changed

+91
-25
lines changed

6 files changed

+91
-25
lines changed

frontend/src/app/features/components/registration-validation-history/registration-validation-history.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,7 @@ export class RegistrationValidationHistoryComponent {
108108
this.selectedPlatformId).subscribe({
109109
next: (records) => {
110110
this.currentPage = records.pageInfo;
111-
this.registrationValidationHistory = records.sourceList.filter(
112-
(item: any) => item.registrationStatus !== 'Not Applicable'
113-
);
111+
this.registrationValidationHistory = records.sourceList;
114112
},
115113
complete: () => {
116114
this.loaderService.loadingEnd();

server/StrDss.Common/Constants.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ public static class UploadStatus
639639
public const string Pending = "Pending";
640640
public const string Processed = "Processed";
641641
public const string Failed = "Failed";
642+
public const string NotApplicable = "Not Applicable";
642643
}
643644

644645
public static class RegistrationValidationText
@@ -652,7 +653,7 @@ public static class RegistrationValidationText
652653
public const string ExemptionStatusNotFound = "Exemption status not found.";
653654
public const string StatusNotFound = "Registration validation Api did not return a registration status.";
654655
public const string ValidationException = "Registration validation Api threw an undhandled exception.";
655-
public const string ValidationException404 = "Registration validation Api return a status of 404 (Permit not found).";
656-
public const string ValidationException401 = "Registration validation Api return a status of 401 (Unauthorized access).";
656+
public const string ValidationException404 = "404: Permit not found.";
657+
public const string ValidationException401 = "401: Unauthorized access.";
657658
}
658659
}

server/StrDss.Data/Repositories/UploadDeliveryRepository.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ public async Task<PagedDto<UploadHistoryViewDto>> GetUploadHistory(long? orgId,
171171
if (reportTypes.Any())
172172
{
173173
query = query.Where(x => reportTypes.Contains(x.UploadDeliveryType));
174+
if (reportTypes.Contains(UploadDeliveryTypes.RegistrationData))
175+
{
176+
query = query.Where(x => x.RegistrationStatus != "Not Applicable");
177+
}
174178
}
175179

176180
var history = await Page<DssRentalUploadHistoryView, UploadHistoryViewDto>(query, pageSize, pageNumber, orderBy, direction);

server/StrDss.Service/HttpClients/ServiceCollectionExtension.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static void AddHttpClients(this IServiceCollection services, IConfigurati
4646
var apiKey = config.GetValue<string>("REGISTRATION_API_KEY") ?? "";
4747

4848
client.BaseAddress = new Uri(baseAddress);
49-
client.Timeout = new TimeSpan(0, 2, 0);
49+
client.Timeout = new TimeSpan(0, 0, 20);
5050
client.DefaultRequestHeaders.Clear();
5151
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
5252
client.DefaultRequestHeaders.Add("x-apikey", apiKey);

server/StrDss.Service/PermitValidationService.cs

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@
77
using StrDss.Data.Repositories;
88
using StrDss.Data.Entities;
99
using NetTopologySuite.Geometries;
10+
using System.Text.RegularExpressions;
11+
using System.Text.Json;
1012

1113
namespace StrDss.Service
1214
{
15+
public class ApiErrorResponse
16+
{
17+
public string ErrorMessage { get; set; }
18+
public string RootCause { get; set; }
19+
}
20+
1321
public interface IPermitValidationService
1422
{
1523
Task<(bool isValid, string registrationText)> ValidateRegistrationPermitAsync(string regNo, string unitNumber, string streetNumber, string postalCode);
@@ -51,10 +59,11 @@ public PermitValidationService(IRegistrationApiClient regApiClient, IGeocoderApi
5159
}
5260
};
5361

62+
Response resp;
5463
try
5564
{
5665
_logger.LogInformation("Calling validate permit.");
57-
Response resp = await _regApiClient.ValidatePermitAsync(body, _apiAccount);
66+
resp = await _regApiClient.ValidatePermitAsync(body, _apiAccount);
5867

5968
// If we didn't get a Status field back, then there was an error
6069
if (string.IsNullOrEmpty(resp.Status))
@@ -67,27 +76,36 @@ public PermitValidationService(IRegistrationApiClient regApiClient, IGeocoderApi
6776
else
6877
{
6978
_logger.LogInformation("Validate permit returned an error.");
70-
Dictionary<string, List<string>> errorDetails = resp.Errors
71-
.GroupBy(e => e.Code)
72-
.ToDictionary(g => g.Key, g => g.Select(e => e.Message).ToList());
73-
registrationText = errorDetails.ParseError();
79+
List<string> errorDetails = resp.Errors
80+
.Select(e => $"{e.Code}: {e.Message}")
81+
.ToList();
82+
83+
registrationText = string.Join("\n", resp.Errors.Select(e => $"{e.Code}: {e.Message}"));
7484
}
7585
}
76-
else if (!string.Equals(resp.Status, "ACTIVE", StringComparison.OrdinalIgnoreCase))
86+
else
7787
{
78-
_logger.LogInformation("Permit status is not ACTIVE.");
79-
isValid = false;
80-
registrationText = resp.Status;
88+
_logger.LogInformation("Permit status is: ." + resp.Status);
8189

90+
registrationText = resp.Status;
8291
}
8392
}
84-
catch (ApiException ex)
93+
catch (ApiException ex) when (ex.StatusCode == 401)
8594
{
86-
_logger.LogInformation("Validate permit call threw an Api exception: " + ex.Message);
95+
_logger.LogInformation("Validate permit call return 401: " + ex.Message);
8796
isValid = false;
88-
registrationText = ex.StatusCode == 404 ? RegistrationValidationText.ValidationException404 :
89-
ex.StatusCode == 401 ? RegistrationValidationText.ValidationException401 :
90-
RegistrationValidationText.ValidationException;
97+
registrationText = RegistrationValidationText.ValidationException401;
98+
}
99+
catch (ApiException ex) when (ex.StatusCode == 404)
100+
{
101+
_logger.LogInformation("Validate permit call returned 404: " + ex.Message);
102+
isValid = false;
103+
registrationText = RegistrationValidationText.ValidationException404;
104+
105+
}
106+
catch (ApiException ex)
107+
{
108+
registrationText = HandleApiException(ex);
91109
}
92110
catch (Exception ex)
93111
{
@@ -156,4 +174,38 @@ public PermitValidationService(IRegistrationApiClient regApiClient, IGeocoderApi
156174

157175
return (isExempt, registrationText);
158176
}
177+
178+
private string HandleApiException(ApiException ex)
179+
{
180+
if (ex.StatusCode == 401)
181+
{
182+
_logger.LogInformation("Validate permit call return 401: " + ex.Message);
183+
return RegistrationValidationText.ValidationException401;
184+
}
185+
if (ex.StatusCode == 404)
186+
{
187+
_logger.LogInformation("Validate permit call returned 404: " + ex.Message);
188+
return RegistrationValidationText.ValidationException404;
189+
190+
}
191+
if (ex.StatusCode == 400)
192+
{
193+
var errorResponse = JsonSerializer.Deserialize<ApiErrorResponse>(ex.Response);
194+
if (errorResponse?.RootCause != null)
195+
{
196+
var match = Regex.Match(errorResponse.RootCause, @"code:(?<code>[^,]+),message:(?<message>[^,\]]+)");
197+
if (match.Success)
198+
{
199+
string code = match.Groups["code"].Value;
200+
string message = match.Groups["message"].Value;
201+
return $"{code}: {message}";
202+
}
203+
else
204+
{
205+
return errorResponse.RootCause; // Fallback to the raw rootCause
206+
}
207+
}
208+
}
209+
return RegistrationValidationText.ValidationException;
210+
}
159211
}

server/StrDss.Service/UploadDeliveryService.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -589,19 +589,30 @@ public async Task<PagedDto<UploadHistoryViewDto>> GetUploadHistory(long? orgId,
589589
var contents = new StringBuilder();
590590

591591
csv.Read();
592-
var header = "validation_result," + csv.Parser.RawRecord.TrimEndNewLine();
592+
var header = "code,validation_result," + csv.Parser.RawRecord.TrimEndNewLine();
593593

594594
contents.AppendLine(header);
595595

596596
foreach (var lineId in lines)
597597
{
598598
var line = await _uploadRepo.GetUploadLineWithError(lineId);
599-
var text = line.RegistrationTxt;
600-
if (string.IsNullOrEmpty(text))
599+
var text = string.IsNullOrEmpty(line.RegistrationTxt) ? "Success" : line.RegistrationTxt;
600+
601+
string? code = null;
602+
string? message = null;
603+
604+
if (text.Contains(":"))
601605
{
602-
text = "Success";
606+
var parts = text.Split(':', 2);
607+
code = parts[0].Trim();
608+
message = parts.Length > 1 ? parts[1].Trim() : null;
603609
}
604-
contents.AppendLine($"\"{text}\"," + line.LineText.TrimEndNewLine());
610+
else
611+
{
612+
message = text;
613+
}
614+
615+
contents.AppendLine($"\"{code}\",\"{message}\"," + line.LineText.TrimEndNewLine());
605616
}
606617

607618
return Encoding.UTF8.GetBytes(contents.ToString());

0 commit comments

Comments
 (0)