646 lines
22 KiB
C#
646 lines
22 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using Moq;
|
|
using OrpaonVision.Core.LayerRecognition;
|
|
using OrpaonVision.Core.PartRecognition;
|
|
using OrpaonVision.Core.QuantityValidation;
|
|
using OrpaonVision.Core.Results;
|
|
using OrpaonVision.SiteApp.Runtime.Options;
|
|
using OrpaonVision.SiteApp.Runtime.Services;
|
|
|
|
namespace OrpaonVision.SiteApp.Tests.Runtime.Services;
|
|
|
|
/// <summary>
|
|
/// 数量校验服务单元测试。
|
|
/// </summary>
|
|
[TestClass]
|
|
public class QuantityValidationServiceTests
|
|
{
|
|
private QuantityValidationService _service = null!;
|
|
private Mock<ILogger<QuantityValidationService>> _loggerMock = null!;
|
|
private Mock<IOptions<RuntimeOptions>> _optionsMock = null!;
|
|
private RuntimeOptions _options = null!;
|
|
|
|
[TestInitialize]
|
|
public void TestInitialize()
|
|
{
|
|
_loggerMock = new Mock<ILogger<QuantityValidationService>>();
|
|
_options = new RuntimeOptions();
|
|
_optionsMock = new Mock<IOptions<RuntimeOptions>>();
|
|
_optionsMock.Setup(x => x.Value).Returns(_options);
|
|
|
|
_service = new QuantityValidationService(_loggerMock.Object, _optionsMock.Object);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateExactQuantityAsync_ExactMatch_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(3);
|
|
const int expectedCount = 3;
|
|
|
|
// Act
|
|
var result = await _service.ValidateExactQuantityAsync(parts, expectedCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsTrue(result.Data.IsValid);
|
|
Assert.AreEqual(expectedCount, result.Data.ActualCount);
|
|
Assert.AreEqual(expectedCount, result.Data.ExpectedCount);
|
|
Assert.AreEqual(0, result.Data.Deviation);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateExactQuantityAsync_NotExactMatch_ReturnsFailure()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(2);
|
|
const int expectedCount = 3;
|
|
|
|
// Act
|
|
var result = await _service.ValidateExactQuantityAsync(parts, expectedCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsFalse(result.Data.IsValid);
|
|
Assert.AreEqual(2, result.Data.ActualCount);
|
|
Assert.AreEqual(expectedCount, result.Data.ExpectedCount);
|
|
Assert.AreEqual(-1, result.Data.Deviation);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateExactQuantityAsync_WithPartType_FiltersCorrectly()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestPartsWithTypes();
|
|
const int expectedCount = 2;
|
|
const PartType partType = PartType.Required;
|
|
|
|
// Act
|
|
var result = await _service.ValidateExactQuantityAsync(parts, expectedCount, partType);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsTrue(result.Data.IsValid);
|
|
Assert.AreEqual(partType, result.Data.PartType);
|
|
Assert.AreEqual(expectedCount, result.Data.ActualCount);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateMinimumQuantityAsync_AboveMinimum_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(5);
|
|
const int minCount = 3;
|
|
|
|
// Act
|
|
var result = await _service.ValidateMinimumQuantityAsync(parts, minCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsTrue(result.Data.IsValid);
|
|
Assert.AreEqual(5, result.Data.ActualCount);
|
|
Assert.AreEqual(minCount, result.Data.MinimumCount);
|
|
Assert.AreEqual(2, result.Data.ExcessCount);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateMinimumQuantityAsync_BelowMinimum_ReturnsFailure()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(2);
|
|
const int minCount = 3;
|
|
|
|
// Act
|
|
var result = await _service.ValidateMinimumQuantityAsync(parts, minCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsFalse(result.Data.IsValid);
|
|
Assert.AreEqual(2, result.Data.ActualCount);
|
|
Assert.AreEqual(minCount, result.Data.MinimumCount);
|
|
Assert.AreEqual(0, result.Data.ExcessCount);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateRangeQuantityAsync_WithinRange_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(4);
|
|
const int minCount = 3;
|
|
const int maxCount = 5;
|
|
|
|
// Act
|
|
var result = await _service.ValidateRangeQuantityAsync(parts, minCount, maxCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsTrue(result.Data.IsValid);
|
|
Assert.AreEqual(4, result.Data.ActualCount);
|
|
Assert.AreEqual(minCount, result.Data.MinimumCount);
|
|
Assert.AreEqual(maxCount, result.Data.MaximumCount);
|
|
Assert.IsFalse(result.Data.IsBelowMinimum);
|
|
Assert.IsFalse(result.Data.IsAboveMaximum);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateRangeQuantityAsync_BelowMinimum_ReturnsFailure()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(2);
|
|
const int minCount = 3;
|
|
const int maxCount = 5;
|
|
|
|
// Act
|
|
var result = await _service.ValidateRangeQuantityAsync(parts, minCount, maxCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsFalse(result.Data.IsValid);
|
|
Assert.AreEqual(2, result.Data.ActualCount);
|
|
Assert.AreEqual(minCount, result.Data.MinimumCount);
|
|
Assert.AreEqual(maxCount, result.Data.MaximumCount);
|
|
Assert.IsTrue(result.Data.IsBelowMinimum);
|
|
Assert.IsFalse(result.Data.IsAboveMaximum);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateRangeQuantityAsync_AboveMaximum_ReturnsFailure()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(6);
|
|
const int minCount = 3;
|
|
const int maxCount = 5;
|
|
|
|
// Act
|
|
var result = await _service.ValidateRangeQuantityAsync(parts, minCount, maxCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsFalse(result.Data.IsValid);
|
|
Assert.AreEqual(6, result.Data.ActualCount);
|
|
Assert.AreEqual(minCount, result.Data.MinimumCount);
|
|
Assert.AreEqual(maxCount, result.Data.MaximumCount);
|
|
Assert.IsFalse(result.Data.IsBelowMinimum);
|
|
Assert.IsTrue(result.Data.IsAboveMaximum);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateUniqueQuantityAsync_ExactUniqueCount_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestPartsWithUniqueProperties("serial_number", 3);
|
|
const int expectedUniqueCount = 3;
|
|
const string uniqueProperty = "serial_number";
|
|
|
|
// Act
|
|
var result = await _service.ValidateUniqueQuantityAsync(parts, uniqueProperty, expectedUniqueCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsTrue(result.Data.IsValid);
|
|
Assert.AreEqual(expectedUniqueCount, result.Data.ActualUniqueCount);
|
|
Assert.AreEqual(expectedUniqueCount, result.Data.ExpectedUniqueCount);
|
|
Assert.AreEqual(uniqueProperty, result.Data.UniqueProperty);
|
|
Assert.AreEqual(0, result.Data.DuplicateValues.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateUniqueQuantityAsync_WithDuplicates_ReturnsFailure()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestPartsWithDuplicates("serial_number", 3);
|
|
const int expectedUniqueCount = 3;
|
|
const string uniqueProperty = "serial_number";
|
|
|
|
// Act
|
|
var result = await _service.ValidateUniqueQuantityAsync(parts, uniqueProperty, expectedUniqueCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsFalse(result.Data.IsValid);
|
|
Assert.AreEqual(2, result.Data.ActualUniqueCount); // 3 parts, but 2 unique values
|
|
Assert.AreEqual(expectedUniqueCount, result.Data.ExpectedUniqueCount);
|
|
Assert.AreEqual(uniqueProperty, result.Data.UniqueProperty);
|
|
Assert.AreEqual(1, result.Data.DuplicateValues.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ValidateUniqueQuantityAsync_PropertyNotExists_ReturnsZeroUnique()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(3);
|
|
const int expectedUniqueCount = 3;
|
|
const string uniqueProperty = "nonexistent_property";
|
|
|
|
// Act
|
|
var result = await _service.ValidateUniqueQuantityAsync(parts, uniqueProperty, expectedUniqueCount);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsFalse(result.Data.IsValid);
|
|
Assert.AreEqual(0, result.Data.ActualUniqueCount);
|
|
Assert.AreEqual(expectedUniqueCount, result.Data.ExpectedUniqueCount);
|
|
Assert.AreEqual(uniqueProperty, result.Data.UniqueProperty);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task BatchValidateQuantityAsync_AllRulesPass_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(3);
|
|
var rules = new List<QuantityValidationRule>
|
|
{
|
|
CreateExactQuantityRule("Rule1", 3),
|
|
CreateMinimumQuantityRule("Rule2", 2),
|
|
CreateRangeQuantityRule("Rule3", 2, 4)
|
|
};
|
|
|
|
// Act
|
|
var result = await _service.BatchValidateQuantityAsync(parts, rules);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.AreEqual(3, result.Data.TotalRules);
|
|
Assert.AreEqual(3, result.Data.PassedRules);
|
|
Assert.AreEqual(0, result.Data.FailedRules);
|
|
Assert.AreEqual(100.0, result.Data.OverallPassRate);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task BatchValidateQuantityAsync_SomeRulesFail_ReturnsPartialSuccess()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(3);
|
|
var rules = new List<QuantityValidationRule>
|
|
{
|
|
CreateExactQuantityRule("Rule1", 3), // Pass
|
|
CreateExactQuantityRule("Rule2", 5), // Fail
|
|
CreateMinimumQuantityRule("Rule3", 2) // Pass
|
|
};
|
|
|
|
// Act
|
|
var result = await _service.BatchValidateQuantityAsync(parts, rules);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.AreEqual(3, result.Data.TotalRules);
|
|
Assert.AreEqual(2, result.Data.PassedRules);
|
|
Assert.AreEqual(1, result.Data.FailedRules);
|
|
Assert.AreEqual(66.7, Math.Round(result.Data.OverallPassRate, 1));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task CreateValidationRuleAsync_ValidRule_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var rule = CreateExactQuantityRule("TestRule", 5);
|
|
|
|
// Act
|
|
var result = await _service.CreateValidationRuleAsync(rule);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsNotNull(result.Data.RuleId);
|
|
Assert.AreEqual("TestRule", result.Data.RuleName);
|
|
Assert.AreEqual(QuantityValidationType.Exact, result.Data.ValidationType);
|
|
Assert.IsTrue(result.Data.IsEnabled);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateValidationRuleAsync_ExistingRule_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var rule = CreateExactQuantityRule("TestRule", 5);
|
|
var createResult = await _service.CreateValidationRuleAsync(rule);
|
|
var updatedRule = createResult.Data;
|
|
updatedRule.ExpectedCount = 10;
|
|
updatedRule.RuleDescription = "Updated description";
|
|
|
|
// Act
|
|
var result = await _service.UpdateValidationRuleAsync(updatedRule);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateValidationRuleAsync_NonExistingRule_ReturnsFailure()
|
|
{
|
|
// Arrange
|
|
var rule = CreateExactQuantityRule("TestRule", 5);
|
|
rule.RuleId = Guid.NewGuid();
|
|
|
|
// Act
|
|
var result = await _service.UpdateValidationRuleAsync(rule);
|
|
|
|
// Assert
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual("RULE_NOT_FOUND", result.Code);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteValidationRuleAsync_ExistingRule_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var rule = CreateExactQuantityRule("TestRule", 5);
|
|
var createResult = await _service.CreateValidationRuleAsync(rule);
|
|
|
|
// Act
|
|
var result = await _service.DeleteValidationRuleAsync(createResult.Data.RuleId);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteValidationRuleAsync_NonExistingRule_ReturnsFailure()
|
|
{
|
|
// Arrange
|
|
var nonExistingRuleId = Guid.NewGuid();
|
|
|
|
// Act
|
|
var result = await _service.DeleteValidationRuleAsync(nonExistingRuleId);
|
|
|
|
// Assert
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual("RULE_NOT_FOUND", result.Code);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetValidationRulesAsync_NoFilters_ReturnsAllRules()
|
|
{
|
|
// Arrange
|
|
await _service.CreateValidationRuleAsync(CreateExactQuantityRule("Rule1", 5));
|
|
await _service.CreateValidationRuleAsync(CreateMinimumQuantityRule("Rule2", 3));
|
|
await _service.CreateValidationRuleAsync(CreateRangeQuantityRule("Rule3", 2, 4));
|
|
|
|
// Act
|
|
var result = await _service.GetValidationRulesAsync();
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsTrue(result.Data.Count >= 3); // At least the 3 rules we created plus default rules
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetValidationRulesAsync_WithFilters_ReturnsFilteredRules()
|
|
{
|
|
// Arrange
|
|
await _service.CreateValidationRuleAsync(CreateExactQuantityRule("Rule1", 5, "ProductA", 1));
|
|
await _service.CreateValidationRuleAsync(CreateMinimumQuantityRule("Rule2", 3, "ProductB", 2));
|
|
await _service.CreateValidationRuleAsync(CreateRangeQuantityRule("Rule3", 2, 4, "ProductA", 2));
|
|
|
|
// Act
|
|
var result = await _service.GetValidationRulesAsync("ProductA", 2);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.AreEqual(1, result.Data.Count); // Only Rule3 matches both filters
|
|
Assert.AreEqual("Rule3", result.Data.First().RuleName);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetValidationStatisticsAsync_WithHistory_ReturnsStatistics()
|
|
{
|
|
// Arrange
|
|
var parts = CreateTestParts(3);
|
|
var startTime = DateTime.UtcNow.AddHours(-1);
|
|
var endTime = DateTime.UtcNow;
|
|
|
|
// Perform some validations to generate history
|
|
await _service.ValidateExactQuantityAsync(parts, 3);
|
|
await _service.ValidateMinimumQuantityAsync(parts, 2);
|
|
await _service.ValidateRangeQuantityAsync(parts, 2, 4);
|
|
|
|
// Act
|
|
var result = await _service.GetValidationStatisticsAsync(startTime, endTime);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.IsTrue(result.Data.TotalValidations >= 3);
|
|
Assert.IsTrue(result.Data.ByValidationType.Count > 0);
|
|
Assert.IsTrue(result.Data.OverallSuccessRate >= 0);
|
|
}
|
|
|
|
#region Helper Methods
|
|
|
|
private static List<MappedPart> CreateTestParts(int count)
|
|
{
|
|
var parts = new List<MappedPart>();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
parts.Add(new MappedPart
|
|
{
|
|
PartId = Guid.NewGuid(),
|
|
PartCode = $"PART-{i:D3}",
|
|
PartName = $"Test Part {i}",
|
|
PartType = PartType.Required,
|
|
OriginalClass = "component_a",
|
|
MappingConfidence = 0.9,
|
|
DetectionConfidence = 0.85,
|
|
OverallConfidence = 0.875,
|
|
BoundingBox = new BoundingBox
|
|
{
|
|
X = i * 10,
|
|
Y = i * 10,
|
|
Width = 50,
|
|
Height = 50,
|
|
Confidence = 0.85,
|
|
Class = "component_a"
|
|
},
|
|
PartAttributes = new Dictionary<string, object>(),
|
|
IsValid = true,
|
|
MappingTimeUtc = DateTime.UtcNow
|
|
});
|
|
}
|
|
return parts;
|
|
}
|
|
|
|
private static List<MappedPart> CreateTestPartsWithTypes()
|
|
{
|
|
return new List<MappedPart>
|
|
{
|
|
new MappedPart
|
|
{
|
|
PartId = Guid.NewGuid(),
|
|
PartCode = "PART-001",
|
|
PartName = "Required Part 1",
|
|
PartType = PartType.Required,
|
|
OriginalClass = "component_a",
|
|
MappingConfidence = 0.9,
|
|
DetectionConfidence = 0.85,
|
|
OverallConfidence = 0.875,
|
|
BoundingBox = new BoundingBox { X = 0, Y = 0, Width = 50, Height = 50, Confidence = 0.85, Class = "component_a" },
|
|
PartAttributes = new Dictionary<string, object>(),
|
|
IsValid = true,
|
|
MappingTimeUtc = DateTime.UtcNow
|
|
},
|
|
new MappedPart
|
|
{
|
|
PartId = Guid.NewGuid(),
|
|
PartCode = "PART-002",
|
|
PartName = "Required Part 2",
|
|
PartType = PartType.Required,
|
|
OriginalClass = "component_a",
|
|
MappingConfidence = 0.9,
|
|
DetectionConfidence = 0.85,
|
|
OverallConfidence = 0.875,
|
|
BoundingBox = new BoundingBox { X = 60, Y = 0, Width = 50, Height = 50, Confidence = 0.85, Class = "component_a" },
|
|
PartAttributes = new Dictionary<string, object>(),
|
|
IsValid = true,
|
|
MappingTimeUtc = DateTime.UtcNow
|
|
},
|
|
new MappedPart
|
|
{
|
|
PartId = Guid.NewGuid(),
|
|
PartCode = "PART-003",
|
|
PartName = "Optional Part 1",
|
|
PartType = PartType.Optional,
|
|
OriginalClass = "component_b",
|
|
MappingConfidence = 0.8,
|
|
DetectionConfidence = 0.75,
|
|
OverallConfidence = 0.775,
|
|
BoundingBox = new BoundingBox { X = 120, Y = 0, Width = 50, Height = 50, Confidence = 0.75, Class = "component_b" },
|
|
PartAttributes = new Dictionary<string, object>(),
|
|
IsValid = true,
|
|
MappingTimeUtc = DateTime.UtcNow
|
|
}
|
|
};
|
|
}
|
|
|
|
private static List<MappedPart> CreateTestPartsWithUniqueProperties(string propertyName, int count)
|
|
{
|
|
var parts = new List<MappedPart>();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
parts.Add(new MappedPart
|
|
{
|
|
PartId = Guid.NewGuid(),
|
|
PartCode = $"PART-{i:D3}",
|
|
PartName = $"Test Part {i}",
|
|
PartType = PartType.Required,
|
|
OriginalClass = "component_a",
|
|
MappingConfidence = 0.9,
|
|
DetectionConfidence = 0.85,
|
|
OverallConfidence = 0.875,
|
|
BoundingBox = new BoundingBox
|
|
{
|
|
X = i * 10,
|
|
Y = i * 10,
|
|
Width = 50,
|
|
Height = 50,
|
|
Confidence = 0.85,
|
|
Class = "component_a"
|
|
},
|
|
PartAttributes = new Dictionary<string, object>
|
|
{
|
|
[propertyName] = $"UNIQUE-{i:D3}"
|
|
},
|
|
IsValid = true,
|
|
MappingTimeUtc = DateTime.UtcNow
|
|
});
|
|
}
|
|
return parts;
|
|
}
|
|
|
|
private static List<MappedPart> CreateTestPartsWithDuplicates(string propertyName, int count)
|
|
{
|
|
var parts = new List<MappedPart>();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
parts.Add(new MappedPart
|
|
{
|
|
PartId = Guid.NewGuid(),
|
|
PartCode = $"PART-{i:D3}",
|
|
PartName = $"Test Part {i}",
|
|
PartType = PartType.Required,
|
|
OriginalClass = "component_a",
|
|
MappingConfidence = 0.9,
|
|
DetectionConfidence = 0.85,
|
|
OverallConfidence = 0.875,
|
|
BoundingBox = new BoundingBox
|
|
{
|
|
X = i * 10,
|
|
Y = i * 10,
|
|
Width = 50,
|
|
Height = 50,
|
|
Confidence = 0.85,
|
|
Class = "component_a"
|
|
},
|
|
PartAttributes = new Dictionary<string, object>
|
|
{
|
|
[propertyName] = i < 2 ? "DUPLICATE-001" : $"UNIQUE-{i:D3}" // First two have same value
|
|
},
|
|
IsValid = true,
|
|
MappingTimeUtc = DateTime.UtcNow
|
|
});
|
|
}
|
|
return parts;
|
|
}
|
|
|
|
private static QuantityValidationRule CreateExactQuantityRule(string name, int expectedCount, string productType = "default", int layerNumber = 0)
|
|
{
|
|
return new QuantityValidationRule
|
|
{
|
|
RuleId = Guid.NewGuid(),
|
|
RuleName = name,
|
|
RuleDescription = $"Exact quantity rule for {name}",
|
|
ProductTypeCode = productType,
|
|
LayerNumber = layerNumber,
|
|
ValidationType = QuantityValidationType.Exact,
|
|
ExpectedCount = expectedCount,
|
|
MinimumCount = expectedCount,
|
|
MaximumCount = expectedCount,
|
|
IsEnabled = true,
|
|
Priority = 1,
|
|
CreatedAtUtc = DateTime.UtcNow,
|
|
UpdatedAtUtc = DateTime.UtcNow,
|
|
Version = "1.0"
|
|
};
|
|
}
|
|
|
|
private static QuantityValidationRule CreateMinimumQuantityRule(string name, int minCount, string productType = "default", int layerNumber = 0)
|
|
{
|
|
return new QuantityValidationRule
|
|
{
|
|
RuleId = Guid.NewGuid(),
|
|
RuleName = name,
|
|
RuleDescription = $"Minimum quantity rule for {name}",
|
|
ProductTypeCode = productType,
|
|
LayerNumber = layerNumber,
|
|
ValidationType = QuantityValidationType.Minimum,
|
|
MinimumCount = minCount,
|
|
ExpectedCount = minCount,
|
|
IsEnabled = true,
|
|
Priority = 2,
|
|
CreatedAtUtc = DateTime.UtcNow,
|
|
UpdatedAtUtc = DateTime.UtcNow,
|
|
Version = "1.0"
|
|
};
|
|
}
|
|
|
|
private static QuantityValidationRule CreateRangeQuantityRule(string name, int minCount, int maxCount, string productType = "default", int layerNumber = 0)
|
|
{
|
|
return new QuantityValidationRule
|
|
{
|
|
RuleId = Guid.NewGuid(),
|
|
RuleName = name,
|
|
RuleDescription = $"Range quantity rule for {name}",
|
|
ProductTypeCode = productType,
|
|
LayerNumber = layerNumber,
|
|
ValidationType = QuantityValidationType.Range,
|
|
MinimumCount = minCount,
|
|
MaximumCount = maxCount,
|
|
ExpectedCount = (minCount + maxCount) / 2,
|
|
IsEnabled = true,
|
|
Priority = 3,
|
|
CreatedAtUtc = DateTime.UtcNow,
|
|
UpdatedAtUtc = DateTime.UtcNow,
|
|
Version = "1.0"
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
}
|