Remove ShopWorker entity and migrate worker identity to ApplicationUser
Removes the ShopWorker and ShopWorkerRoleCost entities, all related DTOs, mappings, controllers, views, and import/export paths. Worker identity is now handled entirely through ApplicationUser with per-user LaborCostPerHour. ShopWorkerRoleCosts table remains in production pending manual data migration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -133,7 +133,6 @@ public class AccountDataExportController : Controller
|
||||
case "Inventory": await AddInventorySheet(package, companyId, headerColor); break;
|
||||
case "Equipment": await AddEquipmentSheet(package, companyId, headerColor); break;
|
||||
case "Vendors": await AddVendorsSheet(package, companyId, headerColor); break;
|
||||
case "ShopWorkers": await AddShopWorkersSheet(package, companyId, headerColor); break;
|
||||
case "Users": await AddUsersSheet(package, companyId, headerColor); break;
|
||||
}
|
||||
}
|
||||
@@ -182,7 +181,6 @@ public class AccountDataExportController : Controller
|
||||
case "Inventory": WriteCsvEntry(zip, "Inventory.csv", await BuildInventoryCsv(companyId)); break;
|
||||
case "Equipment": WriteCsvEntry(zip, "Equipment.csv", await BuildEquipmentCsv(companyId)); break;
|
||||
case "Vendors": WriteCsvEntry(zip, "Vendors.csv", await BuildVendorsCsv(companyId)); break;
|
||||
case "ShopWorkers": WriteCsvEntry(zip, "ShopWorkers.csv", await BuildShopWorkersCsv(companyId)); break;
|
||||
case "Users": WriteCsvEntry(zip, "Users.csv", await BuildUsersCsv(companyId)); break;
|
||||
}
|
||||
}
|
||||
@@ -268,12 +266,6 @@ public class AccountDataExportController : Controller
|
||||
.Where(s => s.CompanyId == companyId && !s.IsDeleted)
|
||||
.OrderBy(s => s.CompanyName).ToListAsync();
|
||||
|
||||
/// <summary>Fetches all non-deleted shop workers for the company.</summary>
|
||||
private Task<List<ShopWorker>> FetchShopWorkersAsync(int companyId) =>
|
||||
_db.ShopWorkers.AsNoTracking().IgnoreQueryFilters()
|
||||
.Where(w => w.CompanyId == companyId && !w.IsDeleted)
|
||||
.OrderBy(w => w.Name).ToListAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Fetches all users for the company. <c>IsDeleted</c> is intentionally omitted because
|
||||
/// Identity users use <c>IsActive = false</c> for soft-deletion, not the base-entity flag.
|
||||
@@ -462,23 +454,6 @@ public class AccountDataExportController : Controller
|
||||
AutoFit(ws, headers.Length);
|
||||
}
|
||||
|
||||
private async Task AddShopWorkersSheet(ExcelPackage pkg, int companyId, Color hdr)
|
||||
{
|
||||
var data = await FetchShopWorkersAsync(companyId);
|
||||
var ws = pkg.Workbook.Worksheets.Add("Shop Workers");
|
||||
var headers = new[] { "ID", "Name", "Role", "Phone", "Email", "Active", "Notes" };
|
||||
WriteHeader(ws, headers, hdr);
|
||||
for (int i = 0; i < data.Count; i++)
|
||||
{
|
||||
var r = i + 2; var w = data[i];
|
||||
ws.Cells[r, 1].Value = w.Id; ws.Cells[r, 2].Value = w.Name;
|
||||
ws.Cells[r, 3].Value = w.Role.ToString(); ws.Cells[r, 4].Value = w.Phone;
|
||||
ws.Cells[r, 5].Value = w.Email; ws.Cells[r, 6].Value = w.IsActive ? "Yes" : "No";
|
||||
ws.Cells[r, 7].Value = w.Notes;
|
||||
}
|
||||
AutoFit(ws, headers.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a "Users" worksheet. All users (active and inactive) are included because Identity
|
||||
/// uses <c>IsActive = false</c> for soft-deletion; <c>IsDeleted</c> is not applicable here.
|
||||
@@ -611,17 +586,6 @@ public class AccountDataExportController : Controller
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Column names match <c>ShopWorkerImportDto</c> exactly so the file can be re-imported.</summary>
|
||||
private async Task<string> BuildShopWorkersCsv(int companyId)
|
||||
{
|
||||
var data = await FetchShopWorkersAsync(companyId);
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Name,Role,Phone,Email,IsActive,Notes");
|
||||
foreach (var w in data)
|
||||
sb.AppendLine($"{CsvEscape(w.Name)},{w.Role},{CsvEscape(w.Phone)},{CsvEscape(w.Email)},{w.IsActive.ToString().ToLower()},{CsvEscape(w.Notes)}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All users (active and inactive) are exported for completeness and compliance — mirrors
|
||||
/// the reasoning in <see cref="AddUsersSheet"/> and <see cref="FetchUsersAsync"/>.
|
||||
@@ -675,13 +639,13 @@ public class AccountDataExportController : Controller
|
||||
|
||||
/// <summary>
|
||||
/// Returns the subset of selected sheet names reordered into the canonical export sequence
|
||||
/// (Customers → Jobs → Quotes → Invoices → Inventory → Equipment → Vendors → ShopWorkers → Users).
|
||||
/// (Customers → Jobs → Quotes → Invoices → Inventory → Equipment → Vendors → Users).
|
||||
/// Guarantees consistent file layout regardless of the order check-boxes were ticked on the form.
|
||||
/// Sheet names not in the canonical list are silently dropped.
|
||||
/// </summary>
|
||||
private static string[] OrderSheets(string[] sheets)
|
||||
{
|
||||
var order = new[] { "Customers", "Jobs", "Quotes", "Invoices", "Inventory", "Equipment", "Vendors", "ShopWorkers", "Users" };
|
||||
var order = new[] { "Customers", "Jobs", "Quotes", "Invoices", "Inventory", "Equipment", "Vendors", "Users" };
|
||||
return order.Where(sheets.Contains).ToArray();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user