Files
BI/server/DongfangHydro.Dashboard.Tests/BomDataApiTests.cs
T

213 lines
8.3 KiB
C#

using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using DongfangHydro.Dashboard.Api.Data;
using DongfangHydro.Dashboard.Api.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace DongfangHydro.Dashboard.Tests;
public sealed class BomDataApiTests(DashboardApiFactory factory)
: IClassFixture<DashboardApiFactory>
{
[Fact]
public async Task MaterialQuotas_supports_category_keyword_and_paging()
{
using var client = factory.CreateClient();
Guid orderId;
await using (var scope = factory.Services.CreateAsyncScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<DashboardDbContext>();
orderId = await dbContext.ProductionOrders.Select(order => order.Id).FirstAsync();
dbContext.MaterialQuotas.AddRange(
CreateQuota(orderId, "钢板", "1010100182", "钢板/Q235B", 9),
CreateQuota(orderId, "标准件", "1110100001", "螺栓/8.8级", 188));
await dbContext.SaveChangesAsync();
}
var response = await client.GetAsync(
$"/api/orders/{orderId}/material-quotas?category=钢板&keyword=Q235B&page=1&pageSize=10");
var body = await response.Content.ReadFromJsonAsync<JsonElement>();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(1, body.GetProperty("total").GetInt32());
var item = Assert.Single(body.GetProperty("items").EnumerateArray());
Assert.Equal("钢板", item.GetProperty("category").GetString());
Assert.Equal("1010100182", item.GetProperty("materialCode").GetString());
Assert.Equal(33.61m, item.GetProperty("netWeight").GetDecimal());
Assert.Equal(35.6266m, item.GetProperty("consumptionQuota").GetDecimal());
Assert.Equal("33.61", item.GetProperty("netWeightText").GetString());
Assert.Equal("35.6266", item.GetProperty("consumptionQuotaText").GetString());
Assert.Equal(9, item.GetProperty("sourceRow").GetInt32());
}
[Fact]
public async Task Tree_exposes_imported_bom_fields()
{
using var client = factory.CreateClient();
Guid orderId;
Guid nodeId;
await using (var scope = factory.Services.CreateAsyncScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<DashboardDbContext>();
var node = await dbContext.ProductionNodes.FirstAsync(item => item.NodeType == "process");
orderId = node.OrderId;
nodeId = node.Id;
node.Specification = "M16";
node.Material = "标准件";
node.UnitWeight = 0.2m;
node.TotalWeight = 1.6m;
node.UnitWeightText = "0.2";
node.TotalWeightText = "1.6";
node.BomQuantity = -8m;
node.BomQuantityText = "-8";
node.Remark = "镀锌";
node.SourceSequence = "1.1.2";
node.SourceSheet = "明细";
node.SourceRow = 10;
await dbContext.SaveChangesAsync();
}
var root = await client.GetFromJsonAsync<JsonElement>($"/api/orders/{orderId}/tree");
var nodeJson = FindNode(root, nodeId);
Assert.Equal("M16", nodeJson.GetProperty("specification").GetString());
Assert.Equal("标准件", nodeJson.GetProperty("material").GetString());
Assert.Equal(0.2m, nodeJson.GetProperty("unitWeight").GetDecimal());
Assert.Equal(1.6m, nodeJson.GetProperty("totalWeight").GetDecimal());
Assert.Equal("0.2", nodeJson.GetProperty("unitWeightText").GetString());
Assert.Equal("1.6", nodeJson.GetProperty("totalWeightText").GetString());
Assert.Equal(-8m, nodeJson.GetProperty("bomQuantity").GetDecimal());
Assert.Equal("-8", nodeJson.GetProperty("bomQuantityText").GetString());
Assert.Equal("镀锌", nodeJson.GetProperty("remark").GetString());
Assert.Equal("1.1.2", nodeJson.GetProperty("sourceSequence").GetString());
Assert.Equal("明细", nodeJson.GetProperty("sourceSheet").GetString());
Assert.Equal(10, nodeJson.GetProperty("sourceRow").GetInt32());
}
[Fact]
public async Task Material_leaf_accepts_direct_progress_updates()
{
using var client = factory.CreateClient();
var orderId = Guid.NewGuid();
var rootId = Guid.NewGuid();
var materialId = Guid.NewGuid();
await using (var scope = factory.Services.CreateAsyncScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<DashboardDbContext>();
dbContext.ProductionOrders.Add(new ProductionOrder
{
Id = orderId,
Code = $"ZZ-MAT-{orderId:N}"[..24],
ProductName = "物料报工测试",
BatchQty = 1,
RequiredQty = 10,
Status = "waiting",
RiskLevel = "normal",
DataSource = "test",
CreatedAt = DateTimeOffset.UtcNow,
UpdatedAt = DateTimeOffset.UtcNow,
RowVersion = [1],
});
dbContext.ProductionNodes.AddRange(
new ProductionNode
{
Id = rootId,
OrderId = orderId,
Code = "ROOT",
Name = "测试订单",
NodeType = "order",
SupplyType = "self_made",
RequiredQty = 10,
Status = "waiting",
RiskLevel = "normal",
UpdatedAt = DateTimeOffset.UtcNow,
RowVersion = [1],
},
new ProductionNode
{
Id = materialId,
OrderId = orderId,
ParentNodeId = rootId,
Code = "MAT-01",
Name = "钢板",
Level = 1,
NodeType = "material",
SupplyType = "purchased",
RequiredQty = 10,
Status = "waiting",
RiskLevel = "normal",
UpdatedAt = DateTimeOffset.UtcNow,
RowVersion = [1],
});
await dbContext.SaveChangesAsync();
}
var tree = await client.GetFromJsonAsync<JsonElement>($"/api/orders/{orderId}/tree");
var material = FindNode(tree, materialId);
var response = await client.PatchAsJsonAsync(
$"/api/nodes/{materialId}/progress",
new
{
completedQty = 10,
expectedVersion = material.GetProperty("version").GetString(),
status = "done",
riskLevel = "normal",
});
var body = await response.Content.ReadFromJsonAsync<JsonElement>();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("material", body.GetProperty("node").GetProperty("nodeType").GetString());
Assert.Equal(100, body.GetProperty("node").GetProperty("progress").GetInt32());
}
private static MaterialQuota CreateQuota(
Guid orderId,
string category,
string materialCode,
string materialName,
int sourceRow)
{
return new MaterialQuota
{
Id = Guid.NewGuid(),
OrderId = orderId,
Category = category,
SourceSequence = "1",
MaterialCode = materialCode,
MaterialName = materialName,
Specification = "δ2-1500",
Unit = "kg",
NetWeight = 33.61m,
ConsumptionQuota = 35.6266m,
NetWeightText = "33.61",
ConsumptionQuotaText = "35.6266",
Brand = "无",
Remark = string.Empty,
SourceSheet = "材料定额",
SourceRow = sourceRow,
};
}
private static JsonElement FindNode(JsonElement node, Guid nodeId)
{
if (node.GetProperty("id").GetGuid() == nodeId)
{
return node;
}
foreach (var child in node.GetProperty("children").EnumerateArray())
{
var match = FindNode(child, nodeId);
if (match.ValueKind != JsonValueKind.Undefined)
{
return match;
}
}
return default;
}
}