From ac76b201debac995da3acd0e70bfac77f5a154b2 Mon Sep 17 00:00:00 2001 From: npalOmega Date: Tue, 28 Apr 2026 18:55:14 -0500 Subject: [PATCH] refactor --- .../Api.SeaHavenIndustries.csproj | 2 + .../Controllers/DispatchController.cs | 4 +- .../Controllers/LocationController.cs | 58 ++--- .../Controllers/SyncController.cs | 2 +- .../Controllers/VendorPortalController.cs | 4 +- .../Controllers/WorkOrderController.cs | 4 +- Api.SeaHavenIndustries/Program.cs | 28 +++ Data.SeaHavenIndustries/Models/Locations.cs | 26 ++- FIX_LOCATIONS_SCHEMA.sql | 109 +++++++++ .../Implementation/AccountDataService.cs | 91 ++++++++ .../Implementation/AssetDataService.cs | 91 ++++++++ .../Implementation/CategoryDataService.cs | 56 +++++ .../Implementation/ContactDataService.cs | 156 +++++++++++++ .../Implementation/DispatchDataService.cs | 115 +++++++++ .../Implementation/EmployeeDataService.cs | 92 ++++++++ .../Implementation/FollowUpDataService.cs | 104 +++++++++ .../Implementation/LocationDataService.cs | 98 ++++++++ .../Implementation/PMScheduleDataService.cs | 91 ++++++++ .../Implementation/VendorDataService.cs | 94 ++++++++ .../Implementation/WorkOrderDataService.cs | 189 +++++++++++++++ .../Interfaces/IAccountDataService.cs | 17 ++ .../Interfaces/IAssetDataService.cs | 18 ++ .../Interfaces/ICategoryDataService.cs | 14 ++ .../Interfaces/IContactDataService.cs | 42 ++++ .../Interfaces/IDispatchDataService.cs | 20 ++ .../Interfaces/IEmployeeDataService.cs | 17 ++ .../Interfaces/IFollowUpDataService.cs | 19 ++ .../Interfaces/ILocationDataService.cs | 18 ++ .../Interfaces/IPMScheduleDataService.cs | 18 ++ .../Interfaces/IVendorDataService.cs | 19 ++ .../Interfaces/IWorkOrderDataService.cs | 48 ++++ .../SeaHaven.DataServices.csproj | 17 ++ SeaHaven.Services/DTOs/AccountDTOs.cs | 29 +++ SeaHaven.Services/DTOs/AssetDTOs.cs | 29 +++ SeaHaven.Services/DTOs/ContactDTOs.cs | 67 ++++++ SeaHaven.Services/DTOs/DispatchDTOs.cs | 30 +++ SeaHaven.Services/DTOs/EmployeeDTOs.cs | 40 ++++ SeaHaven.Services/DTOs/FollowUpDTOs.cs | 34 +++ SeaHaven.Services/DTOs/LocationDTOs.cs | 36 +++ SeaHaven.Services/DTOs/PMScheduleDTOs.cs | 32 +++ SeaHaven.Services/DTOs/VendorDTOs.cs | 36 +++ SeaHaven.Services/DTOs/WorkOrderDTOs.cs | 44 ++++ .../Implementation/ContactService.cs | 220 ++++++++++++++++++ .../Implementation/WorkOrderService.cs | 142 +++++++++++ .../Interfaces/IAccountService.cs | 17 ++ SeaHaven.Services/Interfaces/IAssetService.cs | 18 ++ .../Interfaces/IContactService.cs | 41 ++++ .../Interfaces/IDispatchService.cs | 19 ++ .../Interfaces/IEmployeeService.cs | 17 ++ .../Interfaces/IFollowUpService.cs | 18 ++ .../Interfaces/ILocationService.cs | 18 ++ .../Interfaces/IPMScheduleService.cs | 18 ++ .../Interfaces/IVendorService.cs | 17 ++ .../Interfaces/IWorkOrderService.cs | 18 ++ SeaHaven.Services/SeaHaven.Services.csproj | 14 ++ SeaHavenIndustries.sln | 12 + 56 files changed, 2602 insertions(+), 45 deletions(-) create mode 100644 FIX_LOCATIONS_SCHEMA.sql create mode 100644 SeaHaven.DataServices/Implementation/AccountDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/AssetDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/CategoryDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/ContactDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/DispatchDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/EmployeeDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/FollowUpDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/LocationDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/PMScheduleDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/VendorDataService.cs create mode 100644 SeaHaven.DataServices/Implementation/WorkOrderDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IAccountDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IAssetDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/ICategoryDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IContactDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IDispatchDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IEmployeeDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IFollowUpDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/ILocationDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IPMScheduleDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IVendorDataService.cs create mode 100644 SeaHaven.DataServices/Interfaces/IWorkOrderDataService.cs create mode 100644 SeaHaven.DataServices/SeaHaven.DataServices.csproj create mode 100644 SeaHaven.Services/DTOs/AccountDTOs.cs create mode 100644 SeaHaven.Services/DTOs/AssetDTOs.cs create mode 100644 SeaHaven.Services/DTOs/ContactDTOs.cs create mode 100644 SeaHaven.Services/DTOs/DispatchDTOs.cs create mode 100644 SeaHaven.Services/DTOs/EmployeeDTOs.cs create mode 100644 SeaHaven.Services/DTOs/FollowUpDTOs.cs create mode 100644 SeaHaven.Services/DTOs/LocationDTOs.cs create mode 100644 SeaHaven.Services/DTOs/PMScheduleDTOs.cs create mode 100644 SeaHaven.Services/DTOs/VendorDTOs.cs create mode 100644 SeaHaven.Services/DTOs/WorkOrderDTOs.cs create mode 100644 SeaHaven.Services/Implementation/ContactService.cs create mode 100644 SeaHaven.Services/Implementation/WorkOrderService.cs create mode 100644 SeaHaven.Services/Interfaces/IAccountService.cs create mode 100644 SeaHaven.Services/Interfaces/IAssetService.cs create mode 100644 SeaHaven.Services/Interfaces/IContactService.cs create mode 100644 SeaHaven.Services/Interfaces/IDispatchService.cs create mode 100644 SeaHaven.Services/Interfaces/IEmployeeService.cs create mode 100644 SeaHaven.Services/Interfaces/IFollowUpService.cs create mode 100644 SeaHaven.Services/Interfaces/ILocationService.cs create mode 100644 SeaHaven.Services/Interfaces/IPMScheduleService.cs create mode 100644 SeaHaven.Services/Interfaces/IVendorService.cs create mode 100644 SeaHaven.Services/Interfaces/IWorkOrderService.cs create mode 100644 SeaHaven.Services/SeaHaven.Services.csproj diff --git a/Api.SeaHavenIndustries/Api.SeaHavenIndustries.csproj b/Api.SeaHavenIndustries/Api.SeaHavenIndustries.csproj index cd137c4..b1c8fc5 100644 --- a/Api.SeaHavenIndustries/Api.SeaHavenIndustries.csproj +++ b/Api.SeaHavenIndustries/Api.SeaHavenIndustries.csproj @@ -20,6 +20,8 @@ + + diff --git a/Api.SeaHavenIndustries/Controllers/DispatchController.cs b/Api.SeaHavenIndustries/Controllers/DispatchController.cs index 4996a16..b265914 100644 --- a/Api.SeaHavenIndustries/Controllers/DispatchController.cs +++ b/Api.SeaHavenIndustries/Controllers/DispatchController.cs @@ -327,10 +327,10 @@ namespace Api.SeaHavenIndustries.Controllers { dispatch.WorkOrder.Locations.Id, dispatch.WorkOrder.Locations.Name, - dispatch.WorkOrder.Locations.Address, + dispatch.WorkOrder.Locations.Address1, dispatch.WorkOrder.Locations.City, dispatch.WorkOrder.Locations.State, - dispatch.WorkOrder.Locations.ZipCode + dispatch.WorkOrder.Locations.Zip }, WorkOrders = linkedWOs, Checklist = checklist, diff --git a/Api.SeaHavenIndustries/Controllers/LocationController.cs b/Api.SeaHavenIndustries/Controllers/LocationController.cs index 9dbb485..7843b1c 100644 --- a/Api.SeaHavenIndustries/Controllers/LocationController.cs +++ b/Api.SeaHavenIndustries/Controllers/LocationController.cs @@ -30,7 +30,7 @@ namespace Api.SeaHavenIndustries.Controllers query = query.Where(l => (l.Name ?? "").ToLower().Contains(s) || (l.Title ?? "").ToLower().Contains(s) || - (l.Address ?? "").ToLower().Contains(s) || + (l.Address1 ?? "").ToLower().Contains(s) || (l.City ?? "").ToLower().Contains(s)); } @@ -45,15 +45,17 @@ namespace Api.SeaHavenIndustries.Controllers l.Id, l.Name, l.Title, - l.Address, + Address = l.Address1, // Database has Address1, not Address + l.Address1, + l.Address2, l.City, l.State, - l.ZipCode, - l.Phone, - l.Contact, - l.ContactEmail, - l.Status, - l.AccountId + ZipCode = l.Zip, // Database has Zip, not ZipCode + Phone = l.PhoneNumber, // Database has PhoneNumber, not Phone + Contact = (string?)null, // Contact column doesn't exist in database + ContactEmail = l.Email, // Database has Email, not ContactEmail + l.Status + // AccountId doesn't exist in database }) .ToList(); @@ -79,15 +81,17 @@ namespace Api.SeaHavenIndustries.Controllers l.Id, l.Name, l.Title, - l.Address, + Address = l.Address1, // Database has Address1 + l.Address1, + l.Address2, l.City, l.State, - l.ZipCode, - l.Phone, - l.Contact, - l.ContactEmail, - l.Status, - l.AccountId + ZipCode = l.Zip, // Database has Zip + Phone = l.PhoneNumber, // Database has PhoneNumber + Contact = (string?)null, // Contact doesn't exist + ContactEmail = l.Email, // Database has Email + l.Status + // AccountId doesn't exist }) .FirstOrDefaultAsync(); @@ -106,15 +110,15 @@ namespace Api.SeaHavenIndustries.Controllers { Name = model.Name, Title = model.Title, - Address = model.Address, + Address1 = model.Address, // Map to Address1 City = model.City, State = model.State, - ZipCode = model.ZipCode, - Phone = model.Phone, - Contact = model.Contact, - ContactEmail = model.ContactEmail, + Zip = model.ZipCode, // Map to Zip + PhoneNumber = model.Phone, // Map to PhoneNumber + Email = model.ContactEmail, // Map to Email Status = model.Status, - AccountId = model.GetAccountId() + CreatedDate = DateTime.Now + // Contact and AccountId don't exist in database }; _db.Locations.Add(location); @@ -138,15 +142,15 @@ namespace Api.SeaHavenIndustries.Controllers exist.Name = model.Name; exist.Title = model.Title; - exist.Address = model.Address; + exist.Address1 = model.Address; // Map to Address1 exist.City = model.City; exist.State = model.State; - exist.ZipCode = model.ZipCode; - exist.Phone = model.Phone; - exist.Contact = model.Contact; - exist.ContactEmail = model.ContactEmail; + exist.Zip = model.ZipCode; // Map to Zip + exist.PhoneNumber = model.Phone; // Map to PhoneNumber + exist.Email = model.ContactEmail; // Map to Email exist.Status = model.Status; - exist.AccountId = model.GetAccountId(); + exist.LastModificationTime = DateTime.Now; + // Contact and AccountId don't exist in database await _db.SaveChangesAsync(); return Ok(new DataResponse { Message = "Location Updated Successfully", Status = "200" }); diff --git a/Api.SeaHavenIndustries/Controllers/SyncController.cs b/Api.SeaHavenIndustries/Controllers/SyncController.cs index ada5e1b..5d7f778 100644 --- a/Api.SeaHavenIndustries/Controllers/SyncController.cs +++ b/Api.SeaHavenIndustries/Controllers/SyncController.cs @@ -375,7 +375,7 @@ namespace Api.SeaHavenIndustries.Controllers { Name = matchCode, Title = building, - Address = address, + Address1 = address, Status = "Active" }; diff --git a/Api.SeaHavenIndustries/Controllers/VendorPortalController.cs b/Api.SeaHavenIndustries/Controllers/VendorPortalController.cs index 9e3a13b..8841861 100644 --- a/Api.SeaHavenIndustries/Controllers/VendorPortalController.cs +++ b/Api.SeaHavenIndustries/Controllers/VendorPortalController.cs @@ -232,10 +232,10 @@ namespace Api.SeaHavenIndustries.Controllers Location = dispatch.WorkOrder?.Locations == null ? null : new { dispatch.WorkOrder.Locations.Name, - dispatch.WorkOrder.Locations.Address, + dispatch.WorkOrder.Locations.Address1, dispatch.WorkOrder.Locations.City, dispatch.WorkOrder.Locations.State, - dispatch.WorkOrder.Locations.ZipCode + dispatch.WorkOrder.Locations.Zip }, Checklist = checklist, Signoffs = signoffs, diff --git a/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs b/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs index 9ec544c..fba8cdd 100644 --- a/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs +++ b/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs @@ -644,7 +644,7 @@ namespace Api.SeaHavenIndustries.Controllers assignee = s.AssignToUser != null ? s.AssignToUser.FirstName : "", location = s.Locations != null ? s.Locations.Name : "", locationId = s.LocationId, - locationZip = s.Locations != null ? (s.Locations.ZipCode ?? ExtractZip(s.Locations.Address)) : "", + locationZip = s.Locations != null ? (s.Locations.Zip ?? ExtractZip(s.Locations.Address1)) : "", priority = s.Priority, s.Problem, s.Trade, @@ -1123,7 +1123,7 @@ namespace Api.SeaHavenIndustries.Controllers $"{wo.DueDate?.ToString("yyyy-MM-dd") ?? "N/A"}")); var locationName = System.Net.WebUtility.HtmlEncode(primaryWO.Locations?.Name ?? ""); - var locationAddr = System.Net.WebUtility.HtmlEncode(primaryWO.Locations?.Address ?? ""); + var locationAddr = System.Net.WebUtility.HtmlEncode(primaryWO.Locations?.Address1 ?? ""); var subject = $"[{dispatchNumber}] {(workOrders.Count > 1 ? $"{workOrders.Count} Work Orders" : primaryWO.WorkerOrderTitle)} at {primaryWO.Locations?.Name ?? ""}"; var descriptionHtml = System.Net.WebUtility.HtmlEncode(model.Description ?? primaryWO.Description ?? ""); var senderNameHtml = System.Net.WebUtility.HtmlEncode(senderName); diff --git a/Api.SeaHavenIndustries/Program.cs b/Api.SeaHavenIndustries/Program.cs index 1dfb93f..f84a1a6 100644 --- a/Api.SeaHavenIndustries/Program.cs +++ b/Api.SeaHavenIndustries/Program.cs @@ -31,6 +31,7 @@ builder.Services.AddResponseCompression(opts => }); builder.Services.AddCors(option => option.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod())); +// Helper services builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(sp => @@ -41,6 +42,33 @@ builder.Services.AddSingleton(sp if (File.Exists(csvPath)) zipService.Load(csvPath); return zipService; }); + +// ======================================================================== +// MULTI-TIER ARCHITECTURE - Dependency Injection Registration +// ======================================================================== + +// Data Services (Data Access Layer) +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +// Business Services (Business Logic Layer) - Only register services that exist +builder.Services.AddScoped(); +builder.Services.AddScoped(); +// TODO: Add other business services as they are implemented +// - LocationService, EmployeeService, AccountService, VendorService, DispatchService +// - FollowUpService, PMScheduleService, AssetService, CategoryService + +// ======================================================================== + builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; diff --git a/Data.SeaHavenIndustries/Models/Locations.cs b/Data.SeaHavenIndustries/Models/Locations.cs index f32b1de..9d5fdf3 100644 --- a/Data.SeaHavenIndustries/Models/Locations.cs +++ b/Data.SeaHavenIndustries/Models/Locations.cs @@ -6,21 +6,25 @@ namespace Data.SeaHavenIndustries { public class Locations : FullAuditEntity { + public int Id { get; set; } public string? Title { get; set; } public string? Name { get; set; } - public string? Address { get; set; } - public string? City { get; set; } - public string? State { get; set; } - public string? ZipCode { get; set; } - public string? Phone { get; set; } - public string? Contact { get; set; } - public string? ContactEmail { get; set; } - public string? Status { get; set; } public string? Latitude { get; set; } public string? Longitude { get; set; } - public int? AccountId { get; set; } - [ForeignKey("AccountId")] - public Accounts? Account { get; set; } + + // Address fields - match actual database columns + public string? Address1 { get; set; } + public string? Address2 { get; set; } + public string? City { get; set; } + public string? State { get; set; } + public string? Zip { get; set; } + + // Contact fields - match actual database columns + public string? PhoneNumber { get; set; } + public string? Email { get; set; } + public string? Status { get; set; } + + // Navigation Properties public ICollection