diff --git a/src/SharedKernel/SharedKernel.csproj b/src/SharedKernel/SharedKernel.csproj
index 76c2baa..c594d5b 100644
--- a/src/SharedKernel/SharedKernel.csproj
+++ b/src/SharedKernel/SharedKernel.csproj
@@ -8,7 +8,7 @@
Readme.md
Pandatech
MIT
- 1.8.2
+ 1.8.3
Pandatech.SharedKernel
Pandatech Shared Kernel Library
Pandatech, shared kernel, library, OpenAPI, Swagger, utilities, scalar
@@ -18,46 +18,47 @@
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/src/SharedKernel/ValidatorAndMediatR/Validators/CommissionRuleValidator.cs b/src/SharedKernel/ValidatorAndMediatR/Validators/CommissionRuleValidator.cs
new file mode 100644
index 0000000..860a58a
--- /dev/null
+++ b/src/SharedKernel/ValidatorAndMediatR/Validators/CommissionRuleValidator.cs
@@ -0,0 +1,52 @@
+using CommissionCalculator.DTO;
+using FluentValidation;
+using FluentValidation.Validators;
+using SharedKernel.ValidatorAndMediatR.Validators.Files;
+
+namespace SharedKernel.ValidatorAndMediatR.Validators;
+public sealed class CommissionRuleValidator : PropertyValidator
+{
+ public override string Name => "CommissionRuleValidator";
+
+ public override bool IsValid(ValidationContext context, CommissionRule? rule)
+ {
+ if (rule == null || rule.CommissionRangeConfigs.Count == 0)
+ {
+ context.AddFailure("The ranges list cannot be null or empty.");
+ return false;
+ }
+
+ if (rule.CommissionRangeConfigs.Any(
+ r => r is { Type: CommissionType.Percentage, CommissionAmount: < -10 or > 10 }))
+ {
+ context.AddFailure(
+ "For 'Percentage' CommissionType, the CommissionAmount should be between -10 and 10. Commissions over 1000% are not allowed.");
+ return false;
+ }
+
+ if (rule.CommissionRangeConfigs.Count == 1)
+ {
+ if (rule.CommissionRangeConfigs[0].RangeStart != 0 || rule.CommissionRangeConfigs[0].RangeEnd != 0)
+ {
+ context.AddFailure("In case of one range, both 'From' and 'To' should be 0.");
+ return false;
+ }
+
+ if (rule.CommissionRangeConfigs[0].MaxCommission != 0 && rule.CommissionRangeConfigs[0].MaxCommission <
+ rule.CommissionRangeConfigs[0].MinCommission)
+ {
+ context.AddFailure("MaxCommission should be greater than or equal to MinCommission.");
+ return false;
+ }
+
+ return true; //check
+ }
+ else
+ {
+ var rangeValidator = new CommissionRangeValidator();
+ var rangeValidatorResult = rangeValidator.IsValid(context, rule);
+
+ return true && rangeValidatorResult;
+ }
+ }
+}
diff --git a/src/SharedKernel/ValidatorAndMediatR/Validators/Files/CommissionRangeValidator.cs b/src/SharedKernel/ValidatorAndMediatR/Validators/Files/CommissionRangeValidator.cs
new file mode 100644
index 0000000..08e2a25
--- /dev/null
+++ b/src/SharedKernel/ValidatorAndMediatR/Validators/Files/CommissionRangeValidator.cs
@@ -0,0 +1,68 @@
+using CommissionCalculator.DTO;
+using FluentValidation;
+using FluentValidation.Validators;
+
+namespace SharedKernel.ValidatorAndMediatR.Validators.Files;
+public sealed class CommissionRangeValidator : PropertyValidator
+{
+ public override string Name => "CommissionRangeValidator";
+
+ public override bool IsValid(ValidationContext context, CommissionRule? rule)
+ {
+ var startRule = rule!.CommissionRangeConfigs.FirstOrDefault(r => r is { RangeStart: 0, RangeEnd: > 0 });
+ if (startRule == null)
+ {
+ context.AddFailure("There should be at least one rule where From = 0.");
+ return false;
+ }
+
+ if (startRule.MaxCommission != 0 && startRule.MaxCommission < startRule.MinCommission)
+ {
+ context.AddFailure("MaxCommission should be greater than or equal to MinCommission.");
+ return false;
+ }
+
+ var verifiedRules = 1;
+
+ var lastTo = startRule.RangeEnd;
+
+ while (true)
+ {
+ var nextRule = rule.CommissionRangeConfigs.FirstOrDefault(r => r.RangeStart == lastTo);
+ if (nextRule is null && lastTo != 0)
+ {
+ context.AddFailure($"Gap detected. No rule found for 'From = {lastTo}'.");
+ return false;
+ }
+
+ if (nextRule is not null && nextRule.RangeStart == nextRule.RangeEnd)
+ {
+ context.AddFailure("Invalid rule. 'From' and 'To' cannot be equal.");
+ return false;
+ }
+
+ if (nextRule is not null && nextRule.MaxCommission != 0 && nextRule.MaxCommission < nextRule.MinCommission)
+ {
+ context.AddFailure("MaxCommission should be greater than or equal to MinCommission.");
+ return false;
+ }
+
+ if (lastTo == 0)
+ {
+ break;
+ }
+
+ verifiedRules++;
+
+ lastTo = nextRule!.RangeEnd;
+ }
+
+ if (verifiedRules != rule.CommissionRangeConfigs.Count)
+ {
+ context.AddFailure("There is some nested or gap ranges in the rules.");
+ return false;
+ }
+
+ return true; //check
+ }
+}
diff --git a/src/SharedKernel/ValidatorAndMediatR/Validators/ValidatorExtensions.cs b/src/SharedKernel/ValidatorAndMediatR/Validators/ValidatorExtensions.cs
index 0c2634d..b4c143f 100644
--- a/src/SharedKernel/ValidatorAndMediatR/Validators/ValidatorExtensions.cs
+++ b/src/SharedKernel/ValidatorAndMediatR/Validators/ValidatorExtensions.cs
@@ -1,4 +1,5 @@
-using FluentValidation;
+using CommissionCalculator.DTO;
+using FluentValidation;
using Microsoft.AspNetCore.Http;
using SharedKernel.Helpers;
using SharedKernel.ValidatorAndMediatR.Validators.Files;
@@ -80,4 +81,8 @@ public static IRuleBuilderOptions IsXssSanitized(this IRuleBuilder
{
return rb.SetValidator(new FilesMaxCountValidator(maxCount));
}
+ public static IRuleBuilderOptions ValidateCommissionRule(this IRuleBuilder rule)
+ {
+ return rule.SetValidator(new CommissionRuleValidator());
+ }
}
\ No newline at end of file