@page "/projects/{Id:int}/results" @inject ProjectService ProjectService @inject CutListPackingService PackingService @inject NavigationManager Navigation @inject IJSRuntime JS @using CutList.Core @using CutList.Core.Nesting @using CutList.Core.Formatting Results - @(project?.Name ?? "Project") @if (loading) {

Loading...

} else if (project == null) {
Project not found.
} else {

@project.Name

@if (!string.IsNullOrWhiteSpace(project.Customer)) {

Customer: @project.Customer

}
Edit Project
@if (!CanOptimize) {

Cannot Optimize

} else if (packResult != null) { @if (summary!.TotalItemsNotPlaced > 0) {
Items Not Placed

Some items could not be placed. This usually means no stock lengths are configured for the material, or parts are too long.

}

@(summary.TotalInStockBins + summary.TotalToBePurchasedBins)

Total Stock Bars

@summary.TotalPieces

Total Pieces

@ArchUnits.FormatFromInches(summary.TotalWaste)

Total Waste

@summary.Efficiency.ToString("F1")%

Efficiency

In Stock

@summary.TotalInStockBins bars

Ready to cut from existing inventory

To Be Purchased

@summary.TotalToBePurchasedBins bars

Need to order from supplier

@foreach (var materialResult in packResult.MaterialResults) { var materialSummary = summary.MaterialSummaries.First(s => s.Material.Id == materialResult.Material.Id);

@materialResult.Material.DisplayName

@(materialSummary.InStockBins + materialSummary.ToBePurchasedBins) bars
@materialSummary.TotalPieces pieces
@materialSummary.Efficiency.ToString("F1")% efficiency
@materialSummary.InStockBins in stock
@materialSummary.ToBePurchasedBins to purchase
@if (materialResult.PackResult.ItemsNotUsed.Count > 0) {
@materialResult.PackResult.ItemsNotUsed.Count items not placed - No stock lengths available or parts too long.
} @if (materialResult.InStockBins.Count > 0) {
In Stock (@materialResult.InStockBins.Count bars)
@RenderBinList(materialResult.InStockBins) } @if (materialResult.ToBePurchasedBins.Count > 0) {
To Be Purchased (@materialResult.ToBePurchasedBins.Count bars)
@RenderBinList(materialResult.ToBePurchasedBins)
Order Summary:
    @foreach (var group in materialResult.ToBePurchasedBins.GroupBy(b => b.Length).OrderByDescending(g => g.Key)) {
  • @group.Count() x @ArchUnits.FormatFromInches(group.Key)
  • }
}
} } } @code { [Parameter] public int Id { get; set; } private Project? project; private MultiMaterialPackResult? packResult; private MultiMaterialPackingSummary? summary; private bool loading = true; private bool CanOptimize => project != null && project.Parts.Count > 0 && project.CuttingToolId != null; protected override async Task OnInitializedAsync() { project = await ProjectService.GetByIdAsync(Id); if (project != null && CanOptimize) { var kerf = project.CuttingTool?.KerfInches ?? 0.125m; packResult = await PackingService.PackAsync(project.Parts, kerf); summary = PackingService.GetSummary(packResult); } loading = false; } private RenderFragment RenderBinList(List bins) => __builder => {
@{ var binNumber = 1; } @foreach (var bin in bins) { binNumber++; }
# Stock Length Cuts Waste
@binNumber @ArchUnits.FormatFromInches(bin.Length) @foreach (var item in bin.Items) { @(string.IsNullOrWhiteSpace(item.Name) ? ArchUnits.FormatFromInches(item.Length) : $"{item.Name} ({ArchUnits.FormatFromInches(item.Length)})") } @ArchUnits.FormatFromInches(bin.RemainingLength)
}; private async Task PrintReport() { var filename = $"CutList - {project!.Name} - {DateTime.Now:yyyy-MM-dd}"; await JS.InvokeVoidAsync("printWithTitle", filename); } }