133 lines
4.4 KiB
C#
133 lines
4.4 KiB
C#
using DongfangHydro.Dashboard.Api.Domain;
|
||
using DongfangHydro.Dashboard.Api.Services;
|
||
using Xunit;
|
||
|
||
namespace DongfangHydro.Dashboard.Tests;
|
||
|
||
public sealed class ProgressAggregationServiceTests
|
||
{
|
||
[Fact]
|
||
public void Recalculate_WeightsProgressAndBubblesRiskAndDelayToTheOrder()
|
||
{
|
||
var order = new ProductionOrder
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Code = "MO-TEST-001",
|
||
ProductName = "青峪口尾水单向门机 2×160/10",
|
||
};
|
||
var root = Node(order.Id, "ROOT", null, "order", 30, 0);
|
||
var completed = Node(order.Id, "P-01", root.Id, "part", 10, 10);
|
||
var delayed = Node(order.Id, "P-02", root.Id, "part", 20, 10);
|
||
delayed.Status = "delayed";
|
||
delayed.RiskLevel = "critical";
|
||
delayed.DelayDays = 3;
|
||
|
||
new ProgressAggregationService().Recalculate(order, [root, completed, delayed]);
|
||
|
||
Assert.Equal(67, root.Progress);
|
||
Assert.Equal(20, root.CompletedQty);
|
||
Assert.Equal("delayed", root.Status);
|
||
Assert.Equal("critical", root.RiskLevel);
|
||
Assert.Equal(3, root.DelayDays);
|
||
Assert.Equal(67, order.Progress);
|
||
Assert.Equal(20, order.CompletedQty);
|
||
Assert.Equal("delayed", order.Status);
|
||
Assert.Equal("critical", order.RiskLevel);
|
||
Assert.Equal(3, order.DelayDays);
|
||
}
|
||
|
||
[Fact]
|
||
public void Recalculate_MarksParentDoneWhenAllChildrenAreDone()
|
||
{
|
||
var order = new ProductionOrder
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Code = "MO-TEST-002",
|
||
ProductName = "门架",
|
||
};
|
||
var root = Node(order.Id, "ROOT", null, "order", 10, 0);
|
||
var childA = Node(order.Id, "P-01", root.Id, "part", 4, 4);
|
||
var childB = Node(order.Id, "P-02", root.Id, "part", 6, 6);
|
||
|
||
new ProgressAggregationService().Recalculate(order, [root, childA, childB]);
|
||
|
||
Assert.Equal(100, root.Progress);
|
||
Assert.Equal("done", root.Status);
|
||
Assert.Equal("normal", root.RiskLevel);
|
||
Assert.Equal(100, order.Progress);
|
||
Assert.Equal("done", order.Status);
|
||
}
|
||
|
||
[Fact]
|
||
public void Recalculate_KeepsTheParentsPlannedQuantityWhileUsingChildrenAsWeights()
|
||
{
|
||
var order = new ProductionOrder
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Code = "MO-TEST-003",
|
||
ProductName = "大车行走机构",
|
||
};
|
||
var root = Node(order.Id, "ROOT", null, "order", 5, 0);
|
||
var childA = Node(order.Id, "P-01", root.Id, "part", 10, 10);
|
||
var childB = Node(order.Id, "P-02", root.Id, "part", 20, 10);
|
||
|
||
new ProgressAggregationService().Recalculate(order, [root, childA, childB]);
|
||
|
||
Assert.Equal(5, root.RequiredQty);
|
||
Assert.Equal(3, root.CompletedQty);
|
||
Assert.Equal(5, order.RequiredQty);
|
||
Assert.Equal(3, order.CompletedQty);
|
||
Assert.Equal(67, order.Progress);
|
||
}
|
||
|
||
[Theory]
|
||
[InlineData("blocked", 0, "critical")]
|
||
[InlineData("delayed", 1, "warning")]
|
||
[InlineData("in_progress", 3, "critical")]
|
||
public void Recalculate_BubblesOperationalRiskEvenWhenTheLeafRiskWasNotSet(
|
||
string childStatus,
|
||
int delayDays,
|
||
string expectedRisk)
|
||
{
|
||
var order = new ProductionOrder
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Code = "MO-TEST-004",
|
||
ProductName = "门机电气控制系统",
|
||
};
|
||
var root = Node(order.Id, "ROOT", null, "order", 10, 0);
|
||
var child = Node(order.Id, "OP-10", root.Id, "process", 10, 4);
|
||
child.Status = childStatus;
|
||
child.DelayDays = delayDays;
|
||
child.RiskLevel = "normal";
|
||
|
||
new ProgressAggregationService().Recalculate(order, [root, child]);
|
||
|
||
Assert.Equal(expectedRisk, root.RiskLevel);
|
||
Assert.Equal(expectedRisk, order.RiskLevel);
|
||
}
|
||
|
||
private static ProductionNode Node(
|
||
Guid orderId,
|
||
string code,
|
||
Guid? parentId,
|
||
string nodeType,
|
||
int requiredQty,
|
||
int completedQty)
|
||
{
|
||
return new ProductionNode
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
OrderId = orderId,
|
||
ParentNodeId = parentId,
|
||
Code = code,
|
||
Name = code,
|
||
NodeType = nodeType,
|
||
RequiredQty = requiredQty,
|
||
CompletedQty = completedQty,
|
||
Status = completedQty >= requiredQty ? "done" : "in_progress",
|
||
RiskLevel = "normal",
|
||
};
|
||
}
|
||
}
|