refactor: remove stock-transaction service methods, endpoints, and DTOs

No job workflow ever called these (receive/use/adjust/scrap/recalculate)
- inventory quantity tracking is being removed per
docs/superpowers/specs/2026-08-01-remove-inventory-quantity-tracking-design.md.
This commit is contained in:
aj
2026-08-01 10:43:01 -04:00
parent f71cf8ab0a
commit 41dda11062
4 changed files with 0 additions and 278 deletions
@@ -310,7 +310,6 @@ public class JobsController : ControllerBase
LengthInches = s.LengthInches, LengthInches = s.LengthInches,
LengthFormatted = ArchUnits.FormatFromInches((double)s.LengthInches), LengthFormatted = ArchUnits.FormatFromInches((double)s.LengthInches),
Name = s.Name, Name = s.Name,
QuantityOnHand = s.QuantityOnHand,
IsActive = s.IsActive IsActive = s.IsActive
}).ToList()); }).ToList());
} }
@@ -63,7 +63,6 @@ public class StockItemsController : ControllerBase
MaterialId = dto.MaterialId, MaterialId = dto.MaterialId,
LengthInches = (decimal)lengthInches, LengthInches = (decimal)lengthInches,
Name = dto.Name, Name = dto.Name,
QuantityOnHand = dto.QuantityOnHand,
Notes = dto.Notes Notes = dto.Notes
}; };
@@ -118,87 +117,6 @@ public class StockItemsController : ControllerBase
return Ok(items.Select(MapToDto).ToList()); return Ok(items.Select(MapToDto).ToList());
} }
[HttpGet("{id}/transactions")]
public async Task<ActionResult<List<StockTransactionDto>>> GetTransactions(int id, [FromQuery] int? limit = null)
{
var item = await _stockItemService.GetByIdAsync(id);
if (item == null)
return NotFound();
var transactions = await _stockItemService.GetTransactionHistoryAsync(id, limit);
return Ok(transactions.Select(MapTransactionToDto).ToList());
}
[HttpPost("{id}/receive")]
public async Task<ActionResult<StockTransactionDto>> ReceiveStock(int id, AddStockDto dto)
{
try
{
var transaction = await _stockItemService.AddStockAsync(id, dto.Quantity, dto.Notes);
return Ok(MapTransactionToDto(transaction));
}
catch (InvalidOperationException)
{
return NotFound();
}
}
[HttpPost("{id}/use")]
public async Task<ActionResult<StockTransactionDto>> UseStock(int id, UseStockDto dto)
{
try
{
var transaction = await _stockItemService.UseStockAsync(id, dto.Quantity, dto.JobId, dto.Notes);
return Ok(MapTransactionToDto(transaction));
}
catch (InvalidOperationException)
{
return NotFound();
}
}
[HttpPost("{id}/adjust")]
public async Task<ActionResult<StockTransactionDto>> AdjustStock(int id, AdjustStockDto dto)
{
try
{
var transaction = await _stockItemService.AdjustStockAsync(id, dto.NewQuantity, dto.Notes);
return Ok(MapTransactionToDto(transaction));
}
catch (InvalidOperationException)
{
return NotFound();
}
}
[HttpPost("{id}/scrap")]
public async Task<ActionResult<StockTransactionDto>> ScrapStock(int id, ScrapStockDto dto)
{
try
{
var transaction = await _stockItemService.ScrapStockAsync(id, dto.Quantity, dto.Notes);
return Ok(MapTransactionToDto(transaction));
}
catch (InvalidOperationException)
{
return NotFound();
}
}
[HttpPost("{id}/recalculate")]
public async Task<ActionResult<object>> RecalculateStock(int id)
{
try
{
var newQuantity = await _stockItemService.RecalculateQuantityAsync(id);
return Ok(new { QuantityOnHand = newQuantity });
}
catch (InvalidOperationException)
{
return NotFound();
}
}
private static StockItemDto MapToDto(StockItem s) => new() private static StockItemDto MapToDto(StockItem s) => new()
{ {
Id = s.Id, Id = s.Id,
@@ -207,20 +125,7 @@ public class StockItemsController : ControllerBase
LengthInches = s.LengthInches, LengthInches = s.LengthInches,
LengthFormatted = ArchUnits.FormatFromInches((double)s.LengthInches), LengthFormatted = ArchUnits.FormatFromInches((double)s.LengthInches),
Name = s.Name, Name = s.Name,
QuantityOnHand = s.QuantityOnHand,
Notes = s.Notes, Notes = s.Notes,
IsActive = s.IsActive IsActive = s.IsActive
}; };
private static StockTransactionDto MapTransactionToDto(StockTransaction t) => new()
{
Id = t.Id,
StockItemId = t.StockItemId,
Quantity = t.Quantity,
Type = t.Type.ToString(),
JobId = t.JobId,
JobNumber = t.Job?.JobNumber,
Notes = t.Notes,
CreatedAt = t.CreatedAt
};
} }
-39
View File
@@ -8,7 +8,6 @@ public class StockItemDto
public decimal LengthInches { get; set; } public decimal LengthInches { get; set; }
public string LengthFormatted { get; set; } = string.Empty; public string LengthFormatted { get; set; } = string.Empty;
public string? Name { get; set; } public string? Name { get; set; }
public int QuantityOnHand { get; set; }
public string? Notes { get; set; } public string? Notes { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
} }
@@ -18,7 +17,6 @@ public class CreateStockItemDto
public int MaterialId { get; set; } public int MaterialId { get; set; }
public string Length { get; set; } = string.Empty; public string Length { get; set; } = string.Empty;
public string? Name { get; set; } public string? Name { get; set; }
public int QuantityOnHand { get; set; }
public string? Notes { get; set; } public string? Notes { get; set; }
} }
@@ -28,40 +26,3 @@ public class UpdateStockItemDto
public string? Name { get; set; } public string? Name { get; set; }
public string? Notes { get; set; } public string? Notes { get; set; }
} }
public class StockTransactionDto
{
public int Id { get; set; }
public int StockItemId { get; set; }
public int Quantity { get; set; }
public string Type { get; set; } = string.Empty;
public int? JobId { get; set; }
public string? JobNumber { get; set; }
public string? Notes { get; set; }
public DateTime CreatedAt { get; set; }
}
public class AddStockDto
{
public int Quantity { get; set; }
public string? Notes { get; set; }
}
public class UseStockDto
{
public int Quantity { get; set; }
public int? JobId { get; set; }
public string? Notes { get; set; }
}
public class AdjustStockDto
{
public int NewQuantity { get; set; }
public string? Notes { get; set; }
}
public class ScrapStockDto
{
public int Quantity { get; set; }
public string? Notes { get; set; }
}
-143
View File
@@ -108,147 +108,4 @@ public class StockItemService
return await query.AnyAsync(); return await query.AnyAsync();
} }
// Stock transaction methods
public async Task<StockTransaction> AddStockAsync(int stockItemId, int quantity, string? notes = null)
{
await using var context = _factory.CreateDbContext();
var stockItem = await context.StockItems.FindAsync(stockItemId)
?? throw new InvalidOperationException($"Stock item {stockItemId} not found");
var transaction = new StockTransaction
{
StockItemId = stockItemId,
Quantity = quantity,
Type = StockTransactionType.Received,
Notes = notes,
CreatedAt = DateTime.UtcNow
};
stockItem.QuantityOnHand += quantity;
stockItem.UpdatedAt = DateTime.UtcNow;
context.StockTransactions.Add(transaction);
await context.SaveChangesAsync();
return transaction;
}
public async Task<StockTransaction> UseStockAsync(int stockItemId, int quantity, int? jobId = null, string? notes = null)
{
await using var context = _factory.CreateDbContext();
var stockItem = await context.StockItems.FindAsync(stockItemId)
?? throw new InvalidOperationException($"Stock item {stockItemId} not found");
var transaction = new StockTransaction
{
StockItemId = stockItemId,
Quantity = -quantity,
Type = StockTransactionType.Used,
JobId = jobId,
Notes = notes,
CreatedAt = DateTime.UtcNow
};
stockItem.QuantityOnHand -= quantity;
stockItem.UpdatedAt = DateTime.UtcNow;
context.StockTransactions.Add(transaction);
await context.SaveChangesAsync();
return transaction;
}
public async Task<StockTransaction> AdjustStockAsync(int stockItemId, int newQuantity, string? notes = null)
{
await using var context = _factory.CreateDbContext();
var stockItem = await context.StockItems.FindAsync(stockItemId)
?? throw new InvalidOperationException($"Stock item {stockItemId} not found");
var difference = newQuantity - stockItem.QuantityOnHand;
var transaction = new StockTransaction
{
StockItemId = stockItemId,
Quantity = difference,
Type = StockTransactionType.Adjustment,
Notes = notes ?? "Manual adjustment",
CreatedAt = DateTime.UtcNow
};
stockItem.QuantityOnHand = newQuantity;
stockItem.UpdatedAt = DateTime.UtcNow;
context.StockTransactions.Add(transaction);
await context.SaveChangesAsync();
return transaction;
}
public async Task<StockTransaction> ScrapStockAsync(int stockItemId, int quantity, string? notes = null)
{
await using var context = _factory.CreateDbContext();
var stockItem = await context.StockItems.FindAsync(stockItemId)
?? throw new InvalidOperationException($"Stock item {stockItemId} not found");
var transaction = new StockTransaction
{
StockItemId = stockItemId,
Quantity = -quantity,
Type = StockTransactionType.Scrapped,
Notes = notes,
CreatedAt = DateTime.UtcNow
};
stockItem.QuantityOnHand -= quantity;
stockItem.UpdatedAt = DateTime.UtcNow;
context.StockTransactions.Add(transaction);
await context.SaveChangesAsync();
return transaction;
}
public async Task<List<StockTransaction>> GetTransactionHistoryAsync(int stockItemId, int? limit = null)
{
await using var context = _factory.CreateDbContext();
var query = context.StockTransactions
.Include(t => t.Job)
.Where(t => t.StockItemId == stockItemId)
.OrderByDescending(t => t.CreatedAt)
.AsQueryable();
if (limit.HasValue)
{
query = query.Take(limit.Value);
}
return await query.ToListAsync();
}
public async Task<int> RecalculateQuantityAsync(int stockItemId)
{
await using var context = _factory.CreateDbContext();
var stockItem = await context.StockItems.FindAsync(stockItemId)
?? throw new InvalidOperationException($"Stock item {stockItemId} not found");
var calculatedQuantity = await context.StockTransactions
.Where(t => t.StockItemId == stockItemId)
.SumAsync(t => t.Quantity);
if (stockItem.QuantityOnHand != calculatedQuantity)
{
stockItem.QuantityOnHand = calculatedQuantity;
stockItem.UpdatedAt = DateTime.UtcNow;
await context.SaveChangesAsync();
}
return calculatedQuantity;
}
} }