@page "/stock/new" @page "/stock/{Id:int}" @inject StockItemService StockItemService @inject MaterialService MaterialService @inject NavigationManager Navigation @using CutList.Core.Formatting @(IsNew ? "Add Stock Item" : "Edit Stock Item")

@(IsNew ? "Add Stock Item" : $"{stockItem.Material?.DisplayName} - {ArchUnits.FormatFromInches((double)stockItem.LengthInches)}")

@if (loading) {

Loading...

} else {
Stock Item Details
@if (!string.IsNullOrEmpty(errorMessage)) {
@errorMessage
}
@(IsNew ? "Cancel" : "Back to List")
@if (!IsNew) {
Inventory @stockItem.QuantityOnHand on hand
@if (showStockForm) {
Stock Transaction
@if (!string.IsNullOrEmpty(stockFormErrorMessage)) {
@stockFormErrorMessage
}
} @if (transactions.Count == 0) {

No transaction history yet.

} else { @foreach (var txn in transactions) { }
Date Type Qty Notes
@txn.CreatedAt.ToLocalTime().ToString("MM/dd/yy HH:mm") @txn.Type @(txn.Quantity >= 0 ? "+" : "")@txn.Quantity @(txn.Notes ?? "-")
}
}
} @code { [Parameter] public int? Id { get; set; } private StockItem stockItem = new(); private List materials = new(); private List transactions = new(); private bool loading = true; private bool saving; private string? errorMessage; // Stock transaction form private bool showStockForm; private bool savingStockTransaction; private string stockTransactionType = "add"; private int stockQuantity; private string? stockNotes; private string? stockFormErrorMessage; private bool IsNew => !Id.HasValue; protected override async Task OnInitializedAsync() { materials = await MaterialService.GetAllAsync(); if (Id.HasValue) { var existing = await StockItemService.GetByIdAsync(Id.Value); if (existing == null) { Navigation.NavigateTo("stock"); return; } stockItem = existing; transactions = await StockItemService.GetTransactionHistoryAsync(Id.Value, 20); } loading = false; } private string GetTransactionBadgeClass(StockTransactionType type) => type switch { StockTransactionType.Received => "bg-success", StockTransactionType.Used => "bg-primary", StockTransactionType.Adjustment => "bg-warning text-dark", StockTransactionType.Scrapped => "bg-danger", StockTransactionType.Returned => "bg-info", _ => "bg-secondary" }; private void ShowStockForm() { stockTransactionType = "add"; stockQuantity = 0; stockNotes = null; stockFormErrorMessage = null; showStockForm = true; } private void CancelStockForm() { showStockForm = false; stockFormErrorMessage = null; } private async Task SaveStockTransactionAsync() { stockFormErrorMessage = null; savingStockTransaction = true; try { if (stockQuantity <= 0 && stockTransactionType != "adjust") { stockFormErrorMessage = "Quantity must be greater than zero"; return; } if (stockTransactionType == "adjust" && stockQuantity < 0) { stockFormErrorMessage = "Quantity cannot be negative"; return; } switch (stockTransactionType) { case "add": await StockItemService.AddStockAsync(Id!.Value, stockQuantity, stockNotes); break; case "adjust": await StockItemService.AdjustStockAsync(Id!.Value, stockQuantity, stockNotes); break; case "scrap": await StockItemService.ScrapStockAsync(Id!.Value, stockQuantity, stockNotes); break; } // Refresh var updated = await StockItemService.GetByIdAsync(Id!.Value); if (updated != null) { stockItem = updated; } transactions = await StockItemService.GetTransactionHistoryAsync(Id!.Value, 20); showStockForm = false; } finally { savingStockTransaction = false; } } private async Task SaveStockItemAsync() { errorMessage = null; saving = true; try { if (stockItem.MaterialId == 0) { errorMessage = "Please select a material"; return; } if (stockItem.LengthInches <= 0) { errorMessage = "Length must be greater than zero"; return; } var exists = await StockItemService.ExistsAsync( stockItem.MaterialId, stockItem.LengthInches, IsNew ? null : stockItem.Id); if (exists) { errorMessage = "A stock item with this material and length already exists"; return; } try { if (IsNew) { var created = await StockItemService.CreateAsync(stockItem); Navigation.NavigateTo($"stock/{created.Id}"); } else { await StockItemService.UpdateAsync(stockItem); } } catch (Microsoft.EntityFrameworkCore.DbUpdateException) { errorMessage = "A stock item with this material and length already exists (it may have been previously deleted)."; } } finally { saving = false; } } }