From 49a069cef0d83df9205db70cc219962af6c8e0c9 Mon Sep 17 00:00:00 2001 From: Wendell Muntslag Date: Tue, 28 May 2024 10:23:17 +0200 Subject: [PATCH] chore: update pages --- .../Pages/AddCoreRuleCriterion.razor | 7 +- .../Pages/AddCoreRuleCriterion.razor.cs | 12 ++ .../Components/Pages/CoreRules.razor.cs | 6 +- .../Pages/EditCoreRuleCriterion.razor | 6 +- .../Pages/EditCoreRuleCriterion.razor.cs | 6 + .../Extensions/EnumExtensions.cs | 16 +++ src/iLoan.Rules.Web/ILoan.Rules.Web.csproj | 2 +- .../Models/Enums/RuleComparison.cs | 78 ++++++++++++ .../Services/RuleFileGeneratorService.cs | 111 ++++++++++++++++-- src/iLoan.Rules.Web/Services/RulesService.cs | 18 +++ 10 files changed, 248 insertions(+), 14 deletions(-) create mode 100644 src/iLoan.Rules.Web/Extensions/EnumExtensions.cs create mode 100644 src/iLoan.Rules.Web/Models/Enums/RuleComparison.cs diff --git a/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor b/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor index bd485f2..1fd1fab 100644 --- a/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor +++ b/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor @@ -19,7 +19,9 @@ - + @@ -27,7 +29,8 @@ - + diff --git a/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor.cs b/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor.cs index 04357f4..397cc9c 100644 --- a/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor.cs +++ b/src/iLoan.Rules.Web/Components/Pages/AddCoreRuleCriterion.razor.cs @@ -2,11 +2,13 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using DocumentFormat.OpenXml.CustomProperties; using Microsoft.JSInterop; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Radzen; using Radzen.Blazor; +using Microsoft.EntityFrameworkCore; namespace ILoan.Rules.Web.Components.Pages { @@ -32,8 +34,13 @@ namespace ILoan.Rules.Web.Components.Pages [Inject] public RulesService RulesService { get; set; } + public List Properties { get; set; } + public List Comparisons { get; set; } + protected override async Task OnInitializedAsync() { + Properties = RulesService.GetProperties(); + Comparisons = RulesService.GetComparisons(); coreRulesForRuleID = await RulesService.GetCoreRules(); } @@ -80,5 +87,10 @@ namespace ILoan.Rules.Web.Components.Pages } await base.SetParametersAsync(parameters); } + + void OnChange(dynamic args) + { + coreRuleCriterion.Property = args; + } } } \ No newline at end of file diff --git a/src/iLoan.Rules.Web/Components/Pages/CoreRules.razor.cs b/src/iLoan.Rules.Web/Components/Pages/CoreRules.razor.cs index b59db9c..98d97a7 100644 --- a/src/iLoan.Rules.Web/Components/Pages/CoreRules.razor.cs +++ b/src/iLoan.Rules.Web/Components/Pages/CoreRules.razor.cs @@ -122,7 +122,11 @@ namespace ILoan.Rules.Web.Components.Pages protected async Task CoreRuleCriteriaAddButtonClick(MouseEventArgs args, ILoan.Rules.Web.Models.Rules.CoreRule data) { - var dialogResult = await DialogService.OpenAsync("Add CoreRuleCriteria", new Dictionary { {"RuleID" , data.ID} }); + var dialogResult = await DialogService.OpenAsync("Add CoreRuleCriteria", new Dictionary { {"RuleID" , data.ID} }, new DialogOptions + { + Width = "70%" + }); + await GetChildData(data); await CoreRuleCriteriaDataGrid.Reload(); diff --git a/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor b/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor index a70b4b9..504cdfe 100644 --- a/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor +++ b/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor @@ -20,7 +20,8 @@ - + @@ -28,7 +29,8 @@ - + diff --git a/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor.cs b/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor.cs index 85f92e7..7849cad 100644 --- a/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor.cs +++ b/src/iLoan.Rules.Web/Components/Pages/EditCoreRuleCriterion.razor.cs @@ -36,8 +36,14 @@ namespace ILoan.Rules.Web.Components.Pages [Parameter] public int ID { get; set; } + public List Properties { get; set; } + public List Comparisons { get; set; } + protected override async Task OnInitializedAsync() { + Properties = RulesService.GetProperties(); + Comparisons = RulesService.GetComparisons(); + coreRuleCriterion = await RulesService.GetCoreRuleCriterionById(ID); coreRulesForRuleID = await RulesService.GetCoreRules(); diff --git a/src/iLoan.Rules.Web/Extensions/EnumExtensions.cs b/src/iLoan.Rules.Web/Extensions/EnumExtensions.cs new file mode 100644 index 0000000..7de1e7c --- /dev/null +++ b/src/iLoan.Rules.Web/Extensions/EnumExtensions.cs @@ -0,0 +1,16 @@ +namespace ILoan.Rules.Web.Extensions; + +public static class EnumExtensions +{ + public static List ToList() where T : Enum + { + var names = new List(); + + foreach (var name in Enum.GetNames(typeof(T))) + { + names.Add(name); + } + + return names; + } +} \ No newline at end of file diff --git a/src/iLoan.Rules.Web/ILoan.Rules.Web.csproj b/src/iLoan.Rules.Web/ILoan.Rules.Web.csproj index 57e2a97..9439603 100644 --- a/src/iLoan.Rules.Web/ILoan.Rules.Web.csproj +++ b/src/iLoan.Rules.Web/ILoan.Rules.Web.csproj @@ -1,4 +1,4 @@ - + CS0168,CS1998,BL9993,CS0649,CS0436,0436 net8.0 diff --git a/src/iLoan.Rules.Web/Models/Enums/RuleComparison.cs b/src/iLoan.Rules.Web/Models/Enums/RuleComparison.cs new file mode 100644 index 0000000..9808f88 --- /dev/null +++ b/src/iLoan.Rules.Web/Models/Enums/RuleComparison.cs @@ -0,0 +1,78 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +namespace ILoan.Rules.Web.Models.Enums; + +/// +/// The comparison to apply to the rule value. +/// +[Description("The comparison to apply to the rule value")] +public enum RuleComparison +{ + /// + /// The rule should contain a value. + /// + [Display(Name = "contains")] + Contains, + + /// + /// The rule should not contain a value. + /// + [Display(Name = "does not contain")] + DoesNotContain, + + /// + /// The rule should start with a value. + /// + [Display(Name = "starts with")] + StartsWith, + + /// + /// The rule should not start with a value. + /// + [Display(Name = "does not start with")] + DoesNotStartWith, + + /// + /// The rule should be lower than a value. + /// + [Display(Name = "lower than")] + LowerThan, + + /// + /// The rule should be lower than or equal to a value. + /// + [Display(Name = "lower than or equal to")] + LowerThanOrEqualTo, + + /// + /// The rule should be greater than a value. + /// + [Display(Name = "greater than")] + GreaterThan, + + /// + /// The rule should be greater than or equal to a value. + /// + [Display(Name = "greater than or equal to")] + GreaterThanOrEqualTo, + + /// + /// The rule should be equal to a value. + /// + [Display(Name = "is")] + Is, + + /// + /// The rule should not be equal to a value. + /// + [Display(Name = "is not")] + IsNot, + + /// + /// The rule value should be similar to a value. + /// + [Display(Name = "similar to")] + SimilarTo +} + diff --git a/src/iLoan.Rules.Web/Services/RuleFileGeneratorService.cs b/src/iLoan.Rules.Web/Services/RuleFileGeneratorService.cs index cf8e2d1..94b8219 100644 --- a/src/iLoan.Rules.Web/Services/RuleFileGeneratorService.cs +++ b/src/iLoan.Rules.Web/Services/RuleFileGeneratorService.cs @@ -28,9 +28,13 @@ public class RuleFileGeneratorService if (!Directory.Exists(_root)) Directory.CreateDirectory(_root); } - var rules = await _context.CoreRules.Where(rule => rule.ID >= _startRuleId).ToListAsync(); + var rules = await _context.CoreRules + .Include(r => r.CoreRuleCriteria) + .Include(r => r.CoreRuleCriteriaOperators) + .Where(rule => rule.ID >= _startRuleId) + .ToListAsync(); - foreach (var rule in rules.OrderBy(x =>x.ID)) + foreach (var rule in rules.OrderBy(x => x.ID)) { var fileName = $"V2.{_startSeq:000}__{rule.WorkItemId}_Rules_{rule.ID}_{rule.Title}.sql"; @@ -40,7 +44,6 @@ public class RuleFileGeneratorService } var sql = GenerateSqlStatement(rule); - // Simulate writing to a file (you can replace this with actual file writing) Console.WriteLine($"Generating file: {fileName}"); await File.WriteAllTextAsync(Path.Combine(_root, fileName), sql, Encoding.UTF8); _startSeq++; @@ -49,8 +52,12 @@ public class RuleFileGeneratorService private string GenerateSqlStatement(CoreRule rule) { - return $@" --- SQL statement to insert or update the rule + var sqlBuilder = new StringBuilder(); + + if (rule.Update == 0) + { + // SQL for inserting CoreRule + sqlBuilder.AppendLine($@" INSERT INTO core.""Core_Rules"" ( ""ID"", ""RuleName"", ""Source"", ""DefaultThreshold"", ""Blocked"", ""TriggersManualReview"", ""SuggestedResolution"", ""TriggerReason"", ""UseLastRecord"", ""ApplicantType"", ""FilterOnClickthrough"", @@ -65,11 +72,99 @@ INSERT INTO core.""Core_Rules"" ( '{EscapeSingleQuote(rule.DutchSuggestedResolution)}', '{EscapeSingleQuote(rule.DutchFilterOnClickthrough)}', '{EscapeSingleQuote(rule.RuleExplanation)}', '{EscapeSingleQuote(rule.DutchRuleExplanation)}' ); -"; +"); + + // SQL for inserting CoreRuleCriteria + foreach (var criterion in rule.CoreRuleCriteria) + { + sqlBuilder.AppendLine($@" +INSERT INTO core.""Core_RuleCriteria"" ( + ""ID"", ""RuleID"", ""Property"", ""Comparison"", ""Value"", ""ValueIsProperty"", ""ReturnCount"", ""IsThresholdCriterium"" +) VALUES ( + {criterion.ID}, {criterion.RuleID}, '{EscapeSingleQuote(criterion.Property)}', '{EscapeSingleQuote(criterion.Comparison)}', '{EscapeSingleQuote(criterion.Value)}', + {criterion.ValueIsProperty?.ToString().ToUpper() ?? "NULL"}, {criterion.ReturnCount?.ToString().ToUpper() ?? "NULL"}, {criterion.IsThresholdCriterium?.ToString().ToUpper() ?? "NULL"} +); +"); + } + + // SQL for inserting CoreRuleCriteriaOperator + foreach (var coreRuleCriteriaOperator in rule.CoreRuleCriteriaOperators) + { + sqlBuilder.AppendLine($@" +INSERT INTO core.""Core_RuleCriteriaOperator"" ( + ""ID"", ""RuleID"", ""Operator"" +) VALUES ( + {coreRuleCriteriaOperator.ID}, {coreRuleCriteriaOperator.RuleID}, '{EscapeSingleQuote(coreRuleCriteriaOperator.Operator1)}' +); +"); + } + } + else + { + // SQL for updating CoreRule + sqlBuilder.AppendLine($@" +UPDATE core.""Core_Rules"" +SET + ""RuleName"" = '{EscapeSingleQuote(rule.RuleName)}', + ""Source"" = '{EscapeSingleQuote(rule.Source)}', + ""DefaultThreshold"" = {rule.DefaultThreshold?.ToString() ?? "NULL"}, + ""Blocked"" = {rule.Blocked.ToString().ToUpper()}, + ""TriggersManualReview"" = {rule.TriggersManualReview.ToString().ToUpper()}, + ""SuggestedResolution"" = '{EscapeSingleQuote(rule.SuggestedResolution)}', + ""TriggerReason"" = '{EscapeSingleQuote(rule.TriggerReason)}', + ""UseLastRecord"" = {rule.UseLastRecord?.ToString().ToUpper() ?? "NULL"}, + ""ApplicantType"" = '{EscapeSingleQuote(rule.ApplicantType)}', + ""FilterOnClickthrough"" = '{EscapeSingleQuote(rule.FilterOnClickthrough)}', + ""RunBeforeStatus"" = '{EscapeSingleQuote(rule.RunBeforeStatus)}', + ""DisplaySection"" = '{EscapeSingleQuote(rule.DisplaySection)}', + ""WarningField"" = '{EscapeSingleQuote(rule.WarningField)}', + ""DutchRuleName"" = '{EscapeSingleQuote(rule.DutchRuleName)}', + ""DutchTriggerReason"" = '{EscapeSingleQuote(rule.DutchTriggerReason)}', + ""DutchSuggestedResolution"" = '{EscapeSingleQuote(rule.DutchSuggestedResolution)}', + ""DutchFilterOnClickthrough"" = '{EscapeSingleQuote(rule.DutchFilterOnClickthrough)}', + ""RuleExplanation"" = '{EscapeSingleQuote(rule.RuleExplanation)}', + ""DutchRuleExplanation"" = '{EscapeSingleQuote(rule.DutchRuleExplanation)}' +WHERE ""ID"" = {rule.ID}; +"); + + // SQL for updating CoreRuleCriteria + foreach (var criterion in rule.CoreRuleCriteria) + { + sqlBuilder.AppendLine($@" +UPDATE core.""Core_RuleCriteria"" +SET + ""Property"" = '{EscapeSingleQuote(criterion.Property)}', + ""Comparison"" = '{EscapeSingleQuote(criterion.Comparison)}', + ""Value"" = '{EscapeSingleQuote(criterion.Value)}', + ""ValueIsProperty"" = {criterion.ValueIsProperty?.ToString().ToUpper() ?? "NULL"}, + ""ReturnCount"" = {criterion.ReturnCount?.ToString().ToUpper() ?? "NULL"}, + ""IsThresholdCriterium"" = {criterion.IsThresholdCriterium?.ToString().ToUpper() ?? "NULL"} +WHERE ""ID"" = {criterion.ID}; +"); + } + + // SQL for updating CoreRuleCriteriaOperator + foreach (var coreRuleCriteriaOperator in rule.CoreRuleCriteriaOperators) + { + sqlBuilder.AppendLine($@" +UPDATE core.""Core_RuleCriteriaOperator"" +SET + ""Operator"" = '{EscapeSingleQuote(coreRuleCriteriaOperator.Operator1)}' +WHERE ""ID"" = {coreRuleCriteriaOperator.ID}; +"); + } + } + + return sqlBuilder.ToString(); } - private static string? EscapeSingleQuote(string value) + private static string EscapeSingleQuote(string value) { return value?.Replace("'", "''"); } -} \ No newline at end of file +} + +// Usage example: +// var context = new RulesContext(); +// var generator = new RuleFileGeneratorService(context, configuration); +// await generator.GenerateRuleFilesAsync(); diff --git a/src/iLoan.Rules.Web/Services/RulesService.cs b/src/iLoan.Rules.Web/Services/RulesService.cs index 6b4178e..ca340f2 100644 --- a/src/iLoan.Rules.Web/Services/RulesService.cs +++ b/src/iLoan.Rules.Web/Services/RulesService.cs @@ -10,6 +10,9 @@ using Microsoft.EntityFrameworkCore; using Radzen; using ILoan.Rules.Web.Data; +using DocumentFormat.OpenXml.InkML; +using ILoan.Rules.Web.Models.Enums; +using ILoan.Rules.Web.Extensions; namespace ILoan.Rules.Web { @@ -556,5 +559,20 @@ namespace ILoan.Rules.Web return itemToDelete; } + + // get properties from CoreRuleCriterion as a disctinct list for type ahead + public List GetProperties() + { + var properties = context.CoreRuleCriteria.Select(c => c.Property).Distinct().OrderBy(x => x).ToList(); + return properties; } + + public List GetComparisons() + { + return EnumExtensions.ToList(); + } + } + + + } \ No newline at end of file