feat: add BomImportForm file browsing and analysis logic
Task 8: BrowseBom_Click auto-fills DXF folder and derives job name by stripping ' BOM' suffix; BrowseDxf_Click opens folder browser; Analyze_Click reads BOM via BomReader, runs BomAnalyzer, populates DataGridView with material/thickness/parts/qty columns, updates summary label with skipped/unmatched counts, and enables Create Nests button. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,14 +25,103 @@ namespace OpenNest.Forms
|
||||
|
||||
private void BrowseBom_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var dlg = new OpenFileDialog
|
||||
{
|
||||
Title = "Select BOM File",
|
||||
Filter = "Excel Files|*.xlsx|All Files|*.*",
|
||||
FilterIndex = 1,
|
||||
};
|
||||
|
||||
if (dlg.ShowDialog(this) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
txtBomFile.Text = dlg.FileName;
|
||||
|
||||
// Default DXF folder to the same directory as the BOM file
|
||||
if (string.IsNullOrWhiteSpace(txtDxfFolder.Text))
|
||||
txtDxfFolder.Text = Path.GetDirectoryName(dlg.FileName);
|
||||
|
||||
// Derive job name by stripping " BOM" suffix and extension
|
||||
if (string.IsNullOrWhiteSpace(txtJobName.Text))
|
||||
{
|
||||
var name = Path.GetFileNameWithoutExtension(dlg.FileName);
|
||||
if (name.EndsWith(" BOM", StringComparison.OrdinalIgnoreCase))
|
||||
name = name.Substring(0, name.Length - 4).TrimEnd();
|
||||
txtJobName.Text = name;
|
||||
}
|
||||
}
|
||||
|
||||
private void BrowseDxf_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var dlg = new FolderBrowserDialog
|
||||
{
|
||||
Description = "Select DXF Folder",
|
||||
SelectedPath = txtDxfFolder.Text,
|
||||
};
|
||||
|
||||
if (dlg.ShowDialog(this) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
txtDxfFolder.Text = dlg.SelectedPath;
|
||||
}
|
||||
|
||||
private void Analyze_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!File.Exists(txtBomFile.Text))
|
||||
{
|
||||
MessageBox.Show("BOM file does not exist.", "Validation Error",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
List<BomItem> items;
|
||||
using (var reader = new BomReader(txtBomFile.Text))
|
||||
items = reader.GetItems();
|
||||
|
||||
_analysis = BomAnalyzer.Analyze(items, txtDxfFolder.Text);
|
||||
|
||||
PopulateGrid(_analysis);
|
||||
UpdateSummary(_analysis);
|
||||
btnCreateNests.Enabled = _analysis.Groups.Count > 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Error reading BOM: {ex.Message}", "Error",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateGrid(BomAnalysis analysis)
|
||||
{
|
||||
var table = new DataTable();
|
||||
table.Columns.Add("Material", typeof(string));
|
||||
table.Columns.Add("Thickness", typeof(string));
|
||||
table.Columns.Add("Parts", typeof(int));
|
||||
table.Columns.Add("Total Qty", typeof(int));
|
||||
|
||||
foreach (var group in analysis.Groups)
|
||||
{
|
||||
var partCount = group.Parts.Count;
|
||||
var totalQty = group.Parts.Sum(p => p.Item.Qty ?? 0);
|
||||
table.Rows.Add(group.Material, group.Thickness.ToString("0.###"), partCount, totalQty);
|
||||
}
|
||||
|
||||
dgvGroups.DataSource = table;
|
||||
}
|
||||
|
||||
private void UpdateSummary(BomAnalysis analysis)
|
||||
{
|
||||
var parts = new List<string>();
|
||||
if (analysis.Skipped.Count > 0)
|
||||
parts.Add($"{analysis.Skipped.Count} skipped");
|
||||
if (analysis.Unmatched.Count > 0)
|
||||
parts.Add($"{analysis.Unmatched.Count} unmatched");
|
||||
|
||||
lblSummary.Text = parts.Count > 0
|
||||
? string.Join(", ", parts)
|
||||
: string.Empty;
|
||||
}
|
||||
|
||||
private void CreateNests_Click(object sender, EventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user