feat: Add CutList.Web Blazor Server application

Add a new web-based frontend for cut list optimization using:
- Blazor Server with .NET 8
- Entity Framework Core with MSSQL LocalDB
- Full CRUD for Materials, Suppliers, Projects, and Cutting Tools
- Supplier stock length management for quick project setup
- Integration with CutList.Core for bin packing optimization
- Print-friendly HTML reports with efficiency statistics

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-01 21:56:21 -05:00
parent 6db8ab21f4
commit 9868df162d
43 changed files with 4452 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
using CutList.Web.Data;
using CutList.Web.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace CutList.Web.Services;
public class MaterialService
{
private readonly ApplicationDbContext _context;
public static readonly string[] CommonShapes =
{
"Round Tube",
"Square Tube",
"Rectangular Tube",
"Angle",
"Channel",
"Flat Bar",
"Round Bar",
"Square Bar",
"I-Beam",
"Pipe"
};
public MaterialService(ApplicationDbContext context)
{
_context = context;
}
public async Task<List<Material>> GetAllAsync(bool includeInactive = false)
{
var query = _context.Materials.AsQueryable();
if (!includeInactive)
{
query = query.Where(m => m.IsActive);
}
return await query.OrderBy(m => m.Shape).ThenBy(m => m.Size).ToListAsync();
}
public async Task<Material?> GetByIdAsync(int id)
{
return await _context.Materials.FindAsync(id);
}
public async Task<Material> CreateAsync(Material material)
{
material.CreatedAt = DateTime.UtcNow;
_context.Materials.Add(material);
await _context.SaveChangesAsync();
return material;
}
public async Task UpdateAsync(Material material)
{
material.UpdatedAt = DateTime.UtcNow;
_context.Materials.Update(material);
await _context.SaveChangesAsync();
}
public async Task DeleteAsync(int id)
{
var material = await _context.Materials.FindAsync(id);
if (material != null)
{
material.IsActive = false;
await _context.SaveChangesAsync();
}
}
public async Task<bool> ExistsAsync(string shape, string size, int? excludeId = null)
{
var query = _context.Materials.Where(m => m.Shape == shape && m.Size == size && m.IsActive);
if (excludeId.HasValue)
{
query = query.Where(m => m.Id != excludeId.Value);
}
return await query.AnyAsync();
}
}