From a17d8cac49f3e8b96a31a47e7edcd2975d265427 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 16 Feb 2026 08:45:53 -0500 Subject: [PATCH] refactor: consolidate output folder resolution and prefix handling Move ParseDrawingNumber + GetDrawingOutputFolder into Export() before the document-type switch so folder resolution happens once. Extract PrependPrefix helper in PartExporter to deduplicate the prefix guard. Co-Authored-By: Claude Opus 4.6 --- ExportDXF/Services/DxfExportService.cs | 27 ++++++++------------ ExportDXF/Services/PartExporter.cs | 35 +++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/ExportDXF/Services/DxfExportService.cs b/ExportDXF/Services/DxfExportService.cs index ff9bb42..cd0e90d 100644 --- a/ExportDXF/Services/DxfExportService.cs +++ b/ExportDXF/Services/DxfExportService.cs @@ -63,6 +63,9 @@ namespace ExportDXF.Services var startTime = DateTime.Now; + var drawingNumber = ParseDrawingNumber(context); + var outputFolder = _fileExportService.GetDrawingOutputFolder(drawingNumber); + try { _solidWorksService.EnableUserControl(false); @@ -70,15 +73,15 @@ namespace ExportDXF.Services switch (context.ActiveDocument.DocumentType) { case DocumentType.Part: - ExportPart(context); + ExportPart(context, outputFolder); break; case DocumentType.Assembly: - ExportAssembly(context); + ExportAssembly(context, outputFolder); break; case DocumentType.Drawing: - ExportDrawing(context); + ExportDrawing(context, drawingNumber, outputFolder); break; default: @@ -98,7 +101,7 @@ namespace ExportDXF.Services #region Export Methods by Document Type - private void ExportPart(ExportContext context) + private void ExportPart(ExportContext context, string outputFolder) { LogProgress(context, "Active document is a Part"); @@ -109,11 +112,10 @@ namespace ExportDXF.Services return; } - // Export directly to the output folder - _partExporter.ExportSinglePart(part, _fileExportService.OutputFolder, context); + _partExporter.ExportSinglePart(part, outputFolder, context); } - private void ExportAssembly(ExportContext context) + private void ExportAssembly(ExportContext context, string outputFolder) { LogProgress(context, "Active document is an Assembly"); LogProgress(context, "Fetching components..."); @@ -135,11 +137,10 @@ namespace ExportDXF.Services LogProgress(context, $"Found {items.Count} item(s)."); - // Export directly to the output folder - ExportItems(items, _fileExportService.OutputFolder, context); + ExportItems(items, outputFolder, context); } - private void ExportDrawing(ExportContext context) + private void ExportDrawing(ExportContext context, string drawingNumber, string drawingOutputFolder) { LogProgress(context, "Active document is a Drawing"); LogProgress(context, "Finding BOM tables..."); @@ -161,12 +162,6 @@ namespace ExportDXF.Services LogProgress(context, $"Found {items.Count} component(s)"); - // Determine drawing number for file naming - var drawingNumber = ParseDrawingNumber(context); - - // Resolve output folder: /{outputDir}/{equipmentNo}/{drawingNo}/ or flat fallback - var drawingOutputFolder = _fileExportService.GetDrawingOutputFolder(drawingNumber); - // Export drawing to PDF var tempDir = CreateTempWorkDir(); _drawingExporter.ExportToPdf(drawing, tempDir, context); diff --git a/ExportDXF/Services/PartExporter.cs b/ExportDXF/Services/PartExporter.cs index 405bdf5..3683599 100644 --- a/ExportDXF/Services/PartExporter.cs +++ b/ExportDXF/Services/PartExporter.cs @@ -32,6 +32,13 @@ namespace ExportDXF.Services public class PartExporter : IPartExporter { + private readonly IFileExportService _fileExportService; + + public PartExporter(IFileExportService fileExportService) + { + _fileExportService = fileExportService ?? throw new ArgumentNullException(nameof(fileExportService)); + } + public void ExportSinglePart(PartDoc part, string saveDirectory, ExportContext context) { if (part == null) @@ -99,12 +106,22 @@ namespace ExportDXF.Services var templateDrawing = context.GetOrCreateTemplateDrawing(); + // Stash existing file before overwriting + item.StashedFilePath = _fileExportService.StashFile(savePath); + if (ExportPartToDxf(part, item.Component.ReferencedConfiguration, savePath, context)) { item.FileName = Path.GetFileNameWithoutExtension(savePath); + item.ContentHash = Utilities.ContentHasher.ComputeDxfContentHash(savePath); } else { + // Export failed - restore stashed file if we have one + if (item.StashedFilePath != null && File.Exists(item.StashedFilePath)) + { + File.Move(item.StashedFilePath, savePath, overwrite: true); + item.StashedFilePath = null; + } LogExportFailure(item, context); } } @@ -274,7 +291,8 @@ namespace ExportDXF.Services var isDefaultConfig = string.Equals(config, "default", StringComparison.OrdinalIgnoreCase); var name = isDefaultConfig ? title : $"{title} [{config}]"; - return prefix + name; + + return PrependPrefix(name, prefix); } private string GetItemFileName(Item item, string prefix) @@ -282,9 +300,7 @@ namespace ExportDXF.Services prefix = prefix?.Replace("\"", "''") ?? string.Empty; if (string.IsNullOrWhiteSpace(item.ItemNo)) - { - return prefix + item.PartName; - } + return PrependPrefix(item.PartName, prefix); var num = item.ItemNo.PadLeft(2, '0'); // Expected format: {DrawingNo} PT{ItemNo} @@ -293,6 +309,17 @@ namespace ExportDXF.Services : $"{prefix} PT{num}"; } + private string PrependPrefix(string name, string prefix) + { + if (string.IsNullOrEmpty(prefix)) + return name; + + if (name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + return name; + + return prefix + name; + } + private void LogExportFailure(Item item, ExportContext context) { var desc = item.Description?.ToLower() ?? string.Empty;