-
Notifications
You must be signed in to change notification settings - Fork 3
Bug/ab#28307 auto generated 7 digit applicant id error message #1401
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
Changes from all commits
038ea30
9e16199
93fac2c
46c9df8
9a84512
88447e0
3b82893
24a8c41
e1d8bd3
884d1da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,23 @@ | ||
| using System.Threading.Tasks; | ||
| using Microsoft.EntityFrameworkCore; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.Extensions.Logging.Abstractions; | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Threading.Tasks; | ||
| using System.Text.Json; | ||
| using Unity.GrantManager.Applications; | ||
| using Volo.Abp.DependencyInjection; | ||
| using Unity.GrantManager.GrantApplications; | ||
| using Unity.GrantManager.Intakes; | ||
| using System; | ||
| using Unity.GrantManager.Intakes.Mapping; | ||
| using Unity.GrantManager.GrantApplications; | ||
| using Unity.Payments.Events; | ||
| using Volo.Abp; | ||
| using System.Collections.Generic; | ||
| using Unity.GrantManager.Integration.Orgbook; | ||
| using Newtonsoft.Json.Linq; | ||
| using System.Linq; | ||
| using Unity.Modules.Shared.Utils; | ||
| using Microsoft.Extensions.Logging; | ||
| using Unity.Payments.Domain.Suppliers; | ||
| using Unity.Payments.Events; | ||
| using Unity.Payments.Integrations.Cas; | ||
| using Microsoft.Extensions.Logging.Abstractions; | ||
| using Unity.Payments.Suppliers; | ||
| using Unity.Payments.Domain.Suppliers; | ||
| using Volo.Abp; | ||
| using Volo.Abp.DependencyInjection; | ||
|
|
||
| namespace Unity.GrantManager.Applicants; | ||
|
|
||
|
|
@@ -163,16 +164,46 @@ public async Task MatchApplicantOrgNamesAsync() | |
| [RemoteService(true)] | ||
| public async Task<int> GetNextUnityApplicantIdAsync() | ||
| { | ||
| List<Applicant> applicants = await applicantRepository.GetApplicantsWithUnityApplicantIdAsync(); | ||
| // Convert UnityApplicantId to int, filter only valid numbers | ||
| var unityIds = applicants | ||
| .Where(a => int.TryParse(a.UnityApplicantId, out _)) // Ensure it's numeric | ||
| .Select(a => int.Parse(a.UnityApplicantId!)) | ||
| // Finds the first available Unity Applicant ID, starting from 100000. | ||
| var applicantQuery = await applicantRepository.GetQueryableAsync(); | ||
|
|
||
| var relevantUnityIds = await applicantQuery | ||
| .Where(a => a.UnityApplicantId != null) | ||
| .Select(a => new { UnityApplicantId = a.UnityApplicantId, ParsedId = (int?)null }) | ||
| .ToListAsync(); | ||
|
|
||
| var updatedRelevantUnityIds = relevantUnityIds | ||
| .Select(item => | ||
| { | ||
| if (int.TryParse(item.UnityApplicantId, out var parsedId) && parsedId >= 100000) | ||
| { | ||
| return new { UnityApplicantId = item.UnityApplicantId ?? string.Empty, ParsedId = (int?)parsedId }; | ||
| } | ||
| return new { UnityApplicantId = item.UnityApplicantId ?? string.Empty, ParsedId = item.ParsedId }; | ||
| }) | ||
| .ToList(); | ||
|
|
||
| var orderedIds = updatedRelevantUnityIds | ||
| .Where(a => a.ParsedId.HasValue) | ||
| .Select(a => a.ParsedId!.Value) // Use the null-forgiving operator (!) to assert that ParsedId is not null | ||
| .OrderBy(id => id) | ||
| .ToList(); | ||
|
Comment on lines
+170
to
190
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ticket originates from 27913 - Users can click on the 'Generate' button next to the Applicant ID field. The system will then generate an ID with the following pattern: User can edit the generated number Applicant ID already exists. Please enter a unique ID. |
||
| int nextId = unityIds.Count > 0 ? unityIds.Max() + 1 : 000001; | ||
| int candidate = 100000; // Starting ID for availability search. | ||
|
|
||
| return nextId; | ||
| foreach (var id in orderedIds) | ||
| { | ||
| if (id == candidate) | ||
| { | ||
| candidate++; | ||
| } | ||
| else // Gap found: candidate is the first available ID. | ||
| { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return candidate; | ||
| } | ||
|
|
||
| [RemoteService(true)] | ||
|
|
@@ -188,40 +219,37 @@ public async Task<Applicant> UpdateApplicantOrgMatchAsync(Applicant applicant) | |
| { | ||
| string? orgbookLookup = string.IsNullOrEmpty(applicant.OrgNumber) ? applicant.ApplicantName : applicant.OrgNumber; | ||
| if (string.IsNullOrEmpty(orgbookLookup)) return applicant; | ||
|
|
||
| JObject? result = await orgBookService.GetOrgBookQueryAsync(orgbookLookup); | ||
| var orgData = result?.SelectToken("results")?.Children().FirstOrDefault(); | ||
| if (orgData == null) return applicant; | ||
|
|
||
| // Use the built-in System.Text.Json API | ||
| using JsonDocument result = await orgBookService.GetOrgBookAutocompleteQueryAsync(orgbookLookup); | ||
| if (!result.RootElement.TryGetProperty("results", out JsonElement results) || | ||
| results.GetArrayLength() == 0) | ||
| return applicant; | ||
| JsonElement orgData = results[0]; | ||
| await UpdateApplicantOrgNumberAsync(applicant, orgData); | ||
| await UpdateApplicantNamesAsync(applicant, orgData.SelectToken("names")?.Children()); | ||
| await UpdateApplicantNamesAsync(applicant, orgData.GetProperty("names").EnumerateArray()); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| Logger.LogInformation(ex, "UpdateApplicantOrgMatchAsync: Exception: {ExceptionMessage}", ex.Message); | ||
| } | ||
|
|
||
| return applicant; | ||
| } | ||
|
|
||
| private async Task UpdateApplicantOrgNumberAsync(Applicant applicant, JToken orgData) | ||
| private async Task UpdateApplicantOrgNumberAsync(Applicant applicant, JsonElement orgData) | ||
| { | ||
| var orgNumber = orgData.SelectToken("source_id"); | ||
| if (applicant.OrgNumber == null && orgNumber != null) | ||
| if (orgData.TryGetProperty("source_id", out JsonElement orgNumberElement) && applicant.OrgNumber == null) | ||
| { | ||
| applicant.OrgNumber = orgNumber.ToString(); | ||
| applicant.OrgNumber = orgNumberElement.GetString(); | ||
| await applicantRepository.UpdateAsync(applicant); | ||
| } | ||
| } | ||
|
|
||
| private async Task UpdateApplicantNamesAsync(Applicant applicant, IEnumerable<JToken>? namesChildren) | ||
| private async Task UpdateApplicantNamesAsync(Applicant applicant, IEnumerable<JsonElement> namesChildren) | ||
| { | ||
| if (namesChildren == null) return; | ||
|
|
||
| foreach (var name in namesChildren) | ||
| { | ||
| string nameType = name.SelectToken("type")?.ToString() ?? string.Empty; | ||
| string nameText = name.SelectToken("text")?.ToString() ?? string.Empty; | ||
| string nameType = name.TryGetProperty("type", out JsonElement typeEl) ? typeEl.GetString() ?? string.Empty : string.Empty; | ||
| string nameText = name.TryGetProperty("text", out JsonElement textEl) ? textEl.GetString() ?? string.Empty : string.Empty; | ||
|
|
||
| if (nameType == "entity_name") | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The anonymous type includes UnityApplicantId, but that property isn’t used later; consider projecting only ParsedId or parsing inline to simplify the code.