Patch export/import for missing fields; add CustomerContacts export

- DataExportController + AccountDataExportController: add ProjectName to
  Jobs, Quotes, Invoices (XLSX + CSV); add LeadSource + ShipTo fields to
  Customers (XLSX + CSV); add CustomerContacts sheet/CSV (new)
- Both export views: add Customer Contacts checkbox (checked by default)
- CustomerImportDto: add LeadSource + ShipTo* fields
- JobImportDto: add ProjectName
- QuoteImportDto: add ProjectName
- InvoiceImportDto: add Project Name (dual-name alias for round-trip)
- CsvImportService: wire all new import fields to entity creation;
  also patch invoice update path for ProjectName
- Add scripts/purge_imported_data.sql (dry-run T-SQL for data cleanup)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 15:14:27 -04:00
parent 427c52a499
commit 82fb48f7a5
10 changed files with 637 additions and 76 deletions
@@ -605,6 +605,12 @@ public class CsvImportService : ICsvImportService
PaymentTerms = record.PaymentTerms?.Trim() ?? "Net 30",
IsTaxExempt = record.TaxExempt ?? false,
GeneralNotes = record.Notes?.Trim(),
LeadSource = record.LeadSource?.Trim(),
ShipToAddress = record.ShipToAddress?.Trim(),
ShipToCity = record.ShipToCity?.Trim(),
ShipToState = record.ShipToState?.Trim(),
ShipToZipCode = record.ShipToZipCode?.Trim(),
ShipToCountry = record.ShipToCountry?.Trim(),
IsActive = record.IsActive ?? true,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
@@ -1284,6 +1290,7 @@ public class CsvImportService : ICsvImportService
Total = record.Total,
Notes = record.Notes?.Trim(),
Terms = record.TermsAndConditions?.Trim(),
ProjectName = record.ProjectName?.Trim(),
IsCommercial = customerId.HasValue,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
@@ -1557,6 +1564,7 @@ public class CsvImportService : ICsvImportService
CustomerPO = record.CustomerPO?.Trim(),
SpecialInstructions = record.SpecialInstructions?.Trim(),
InternalNotes = record.Notes?.Trim(),
ProjectName = record.ProjectName?.Trim(),
Description = record.Description?.Trim()
?? record.SpecialInstructions?.Trim()
?? "Imported job",
@@ -3146,9 +3154,10 @@ public class CsvImportService : ICsvImportService
existing.DiscountAmount = record.DiscountAmount;
existing.Total = record.Total;
existing.AmountPaid = record.AmountPaid;
existing.CustomerPO = string.IsNullOrWhiteSpace(record.CustomerPO) ? null : record.CustomerPO.Trim();
existing.Terms = string.IsNullOrWhiteSpace(record.Terms) ? null : record.Terms.Trim();
existing.Notes = string.IsNullOrWhiteSpace(record.Notes) ? null : record.Notes.Trim();
existing.CustomerPO = string.IsNullOrWhiteSpace(record.CustomerPO) ? null : record.CustomerPO.Trim();
existing.Terms = string.IsNullOrWhiteSpace(record.Terms) ? null : record.Terms.Trim();
existing.Notes = string.IsNullOrWhiteSpace(record.Notes) ? null : record.Notes.Trim();
existing.ProjectName = string.IsNullOrWhiteSpace(record.ProjectName) ? null : record.ProjectName.Trim();
await _unitOfWork.CompleteAsync();
result.SuccessCount++;
}
@@ -3170,9 +3179,10 @@ public class CsvImportService : ICsvImportService
DiscountAmount = record.DiscountAmount,
Total = record.Total,
AmountPaid = record.AmountPaid,
CustomerPO = string.IsNullOrWhiteSpace(record.CustomerPO) ? null : record.CustomerPO.Trim(),
Terms = string.IsNullOrWhiteSpace(record.Terms) ? null : record.Terms.Trim(),
Notes = string.IsNullOrWhiteSpace(record.Notes) ? null : record.Notes.Trim()
CustomerPO = string.IsNullOrWhiteSpace(record.CustomerPO) ? null : record.CustomerPO.Trim(),
Terms = string.IsNullOrWhiteSpace(record.Terms) ? null : record.Terms.Trim(),
Notes = string.IsNullOrWhiteSpace(record.Notes) ? null : record.Notes.Trim(),
ProjectName = string.IsNullOrWhiteSpace(record.ProjectName) ? null : record.ProjectName.Trim()
};
await _unitOfWork.Invoices.AddAsync(invoice);
await _unitOfWork.CompleteAsync();