@page "/jobs/{Id:int}/results" @inject JobService JobService @inject CutListPackingService PackingService @inject NavigationManager Navigation @inject IJSRuntime JS @using CutList.Core @using CutList.Core.Nesting @using CutList.Core.Formatting Results - @(job?.DisplayName ?? "Job") @if (loading) {

Loading...

} else if (job == null) {
Job not found.
} else {

@job.DisplayName

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

Customer: @job.Customer

}
Edit Job
@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 Job? job; private MultiMaterialPackResult? packResult; private MultiMaterialPackingSummary? summary; private bool loading = true; private bool CanOptimize => job != null && job.Parts.Count > 0 && job.CuttingToolId != null; protected override async Task OnInitializedAsync() { job = await JobService.GetByIdAsync(Id); if (job != null && CanOptimize) { var kerf = job.CuttingTool?.KerfInches ?? 0.125m; // Pass job stock if configured, otherwise packing service uses all available stock packResult = await PackingService.PackAsync(job.Parts, kerf, job.Stock.Count > 0 ? job.Stock : null); 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 - {job!.Name} - {DateTime.Now:yyyy-MM-dd}"; await JS.InvokeVoidAsync("printWithTitle", filename); } }