From 9c78cd96fa61b24e472c28ec5155138cfb09a8ce Mon Sep 17 00:00:00 2001 From: npalOmega Date: Wed, 21 Jan 2026 15:41:19 -0600 Subject: [PATCH] added new controllers --- .../Controllers/AccountController.cs | 205 ++++++++++++++++++ .../Controllers/EmployeeController.cs | 154 +++++++++++++ .../Controllers/FollowUpController.cs | 148 +++++++++++++ .../Controllers/PMScheduleController.cs | 69 ++++++ Api.SeaHavenIndustries/DTOs/Account_DTO.cs | 30 +++ Api.SeaHavenIndustries/DTOs/Employee_DTO.cs | 35 +++ Api.SeaHavenIndustries/DTOs/FollowUp_DTO.cs | 17 ++ Api.SeaHavenIndustries/DTOs/PMSchedule_DTO.cs | 13 ++ .../Auth/ApplicationDbContext.cs | 23 +- Data.SeaHavenIndustries/Models/Accounts.cs | 33 +++ Data.SeaHavenIndustries/Models/Addresses.cs | 26 +++ Data.SeaHavenIndustries/Models/Assets.cs | 21 ++ .../Models/ContactDetails.cs | 23 ++ Data.SeaHavenIndustries/Models/Employee.cs | 122 +++++++++++ Data.SeaHavenIndustries/Models/FollowUps.cs | 32 +++ Data.SeaHavenIndustries/Models/PMSchedules.cs | 16 ++ 16 files changed, 960 insertions(+), 7 deletions(-) create mode 100644 Api.SeaHavenIndustries/Controllers/AccountController.cs create mode 100644 Api.SeaHavenIndustries/Controllers/EmployeeController.cs create mode 100644 Api.SeaHavenIndustries/Controllers/FollowUpController.cs create mode 100644 Api.SeaHavenIndustries/Controllers/PMScheduleController.cs create mode 100644 Api.SeaHavenIndustries/DTOs/Account_DTO.cs create mode 100644 Api.SeaHavenIndustries/DTOs/Employee_DTO.cs create mode 100644 Api.SeaHavenIndustries/DTOs/FollowUp_DTO.cs create mode 100644 Api.SeaHavenIndustries/DTOs/PMSchedule_DTO.cs create mode 100644 Data.SeaHavenIndustries/Models/Accounts.cs create mode 100644 Data.SeaHavenIndustries/Models/Addresses.cs create mode 100644 Data.SeaHavenIndustries/Models/Assets.cs create mode 100644 Data.SeaHavenIndustries/Models/ContactDetails.cs create mode 100644 Data.SeaHavenIndustries/Models/Employee.cs create mode 100644 Data.SeaHavenIndustries/Models/FollowUps.cs create mode 100644 Data.SeaHavenIndustries/Models/PMSchedules.cs diff --git a/Api.SeaHavenIndustries/Controllers/AccountController.cs b/Api.SeaHavenIndustries/Controllers/AccountController.cs new file mode 100644 index 0000000..9fbe7df --- /dev/null +++ b/Api.SeaHavenIndustries/Controllers/AccountController.cs @@ -0,0 +1,205 @@ +using Api.SeaHavenIndustries.DTOs; +using Data.SeaHavenIndustries; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +[ApiController] +[Route("api/Account")] +public class AccountController : Controller +{ + private readonly ApplicationDbContext _db; + + public AccountController(ApplicationDbContext db) + { + _db = db; + } + + // ----------------------------------- + // POST: api/Account/AddAccounts + // ----------------------------------- + [HttpPost("AddAccounts")] + public async Task AddAccounts(Account_DTO dto) + { + try + { + var model = new Accounts + { + Name = dto.Name, + Type = dto.Type, + Importance = dto.Importance, + TerritoryId = dto.TerritoryId, + OwnerEmployeeId = dto.OwnerEmployeeId, + PrivacySetting = dto.PrivacySetting, + About = dto.About, + Tags = dto.Tags, + + Phone = dto.Phone, + Email = dto.Email, + IndustryId = dto.IndustryId, + TimeZone = dto.TimeZone, + Website = dto.Website, + CurrencyCode = dto.CurrencyCode, + ServiceInstructions = dto.ServiceInstructions, + + FacebookUrl = dto.FacebookUrl, + LinkedInUrl = dto.LinkedInUrl, + TwitterUrl = dto.TwitterUrl, + + CreatedDate = DateTime.UtcNow + }; + + _db.Accounts.Add(model); + await _db.SaveChangesAsync(); + + return Ok(new DataResponse + { + Message = "Account added successfully.", + Status = "200" + }); + } + catch (Exception ex) + { + return BadRequest(new Response + { + Status = "Error", + Message = ex.Message + }); + } + } + + // ----------------------------------- + // POST: api/Account/EditAccounts + // ----------------------------------- + [HttpPost("EditAccounts")] + public async Task EditAccounts(EditAccount_DTO dto) + { + try + { + var account = await _db.Accounts.FirstOrDefaultAsync(a => a.Id == dto.Id); + if (account == null) + return BadRequest(new Response { Status = "Error", Message = "Account not found." }); + + account.Name = dto.Name; + account.Type = dto.Type; + account.Importance = dto.Importance; + account.TerritoryId = dto.TerritoryId; + account.OwnerEmployeeId = dto.OwnerEmployeeId; + account.PrivacySetting = dto.PrivacySetting; + account.About = dto.About; + account.Tags = dto.Tags; + + account.Phone = dto.Phone; + account.Email = dto.Email; + account.IndustryId = dto.IndustryId; + account.TimeZone = dto.TimeZone; + account.Website = dto.Website; + account.CurrencyCode = dto.CurrencyCode; + account.ServiceInstructions = dto.ServiceInstructions; + + account.FacebookUrl = dto.FacebookUrl; + account.LinkedInUrl = dto.LinkedInUrl; + account.TwitterUrl = dto.TwitterUrl; + + account.LastModificationTime = DateTime.UtcNow; + + await _db.SaveChangesAsync(); + + return Ok(new DataResponse + { + Message = "Account updated successfully.", + Status = "200" + }); + } + catch (Exception ex) + { + return BadRequest(new Response + { + Status = "Error", + Message = ex.Message + }); + } + } + + // ----------------------------------- + // GET: api/Account/DeleteAccounts?id=5 + // ----------------------------------- + [HttpGet("DeleteAccounts")] + public async Task DeleteAccounts(int id) + { + try + { + var account = await _db.Accounts.FirstOrDefaultAsync(a => a.Id == id); + if (account == null) + return BadRequest(new Response { Status = "Error", Message = "Account not found." }); + + _db.Accounts.Remove(account); + await _db.SaveChangesAsync(); + + return Ok(new DataResponse + { + Message = "Account deleted successfully.", + Status = "200" + }); + } + catch (Exception ex) + { + return BadRequest(new Response + { + Status = "Error", + Message = ex.Message + }); + } + } + + // ----------------------------------- + // GET: api/Account/GetAccountList?search=&page=&pageSize= + // ----------------------------------- + [HttpGet("GetAccountList")] + public IActionResult GetAccountList(string? search = "", int page = 1, int pageSize = 12) + { + search ??= ""; + + var query = _db.Accounts + .Where(a => a.IsDeleted == false || a.IsDeleted == null); + + if (!string.IsNullOrWhiteSpace(search)) + { + var s = search.ToLower(); + query = query.Where(a => + (a.Name ?? "").ToLower().Contains(s) || + (a.Email ?? "").ToLower().Contains(s) || + (a.Phone ?? "").Contains(s) || + (a.Website ?? "").ToLower().Contains(s) + ); + } + + var totalCount = query.Count(); + + var data = query + .OrderByDescending(a => a.Id) + .Skip((page - 1) * pageSize) + .Take(pageSize) + .Select(a => new + { + a.Id, + a.Name, + a.Type, + a.Phone, + a.Email, + Industry = a.IndustryId, + a.Website + }) + .ToList(); + + var viewModel = new Pagination_DTO + { + Data = data, + PageNumber = page, + PageSize = pageSize, + TotalCount = totalCount, + TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize) + }; + + return Ok(viewModel); + } +} diff --git a/Api.SeaHavenIndustries/Controllers/EmployeeController.cs b/Api.SeaHavenIndustries/Controllers/EmployeeController.cs new file mode 100644 index 0000000..c12dbba --- /dev/null +++ b/Api.SeaHavenIndustries/Controllers/EmployeeController.cs @@ -0,0 +1,154 @@ +using Api.SeaHavenIndustries.DTOs; +using Data.SeaHavenIndustries; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +[ApiController] +[Route("api/Employee")] +public class EmployeeController : Controller +{ + private readonly ApplicationDbContext _db; + + public EmployeeController(ApplicationDbContext db) + { + _db = db; + } + + // ----------------------------------- + // POST: api/Employee/AddEmployees + // ----------------------------------- + [HttpPost("AddEmployees")] + public async Task AddEmployees(AddEmployee_DTO dto) + { + var employee = new Employee + { + FirstName = dto.FirstName, + LastName = dto.LastName, + JobTitleId = dto.JobTitleId, + PermissionGroupId = dto.PermissionGroupId, + Status = dto.Status, + LastLogin = dto.LastLogin, + CreatedDate = DateTime.UtcNow + }; + + if (!string.IsNullOrWhiteSpace(dto.Email)) + { + employee.Emails.Add(new EmployeeEmail + { + Address = dto.Email, + IsPrimary = true, + EmailTypeId = 1 + }); + } + + if (!string.IsNullOrWhiteSpace(dto.Phone)) + { + employee.Phones.Add(new EmployeePhone + { + Number = dto.Phone, + Extension = dto.PhoneExtension, + IsPrimary = true, + PhoneTypeId = 1 + }); + } + + _db.Employees.Add(employee); + await _db.SaveChangesAsync(); + + return Ok(new { Message = "Employee added successfully" }); + } + + // ----------------------------------- + // POST: api/Employee/EditEmployees + // ----------------------------------- + [HttpPost("EditEmployees")] + public async Task EditEmployees(EditEmployee_DTO dto) + { + var employee = await _db.Employees + .Include(e => e.Emails) + .Include(e => e.Phones) + .FirstOrDefaultAsync(e => e.Id == dto.Id); + + if (employee == null) + return BadRequest("Employee not found"); + + employee.FirstName = dto.FirstName; + employee.LastName = dto.LastName; + employee.JobTitleId = dto.JobTitleId; + employee.PermissionGroupId = dto.PermissionGroupId; + employee.Status = dto.Status; + employee.LastLogin = dto.LastLogin; + employee.LastModificationTime = DateTime.UtcNow; + + await _db.SaveChangesAsync(); + return Ok(new { Message = "Employee updated successfully" }); + } + + // ----------------------------------- + // GET: api/Employee/GetEmployeeList + // ----------------------------------- + [HttpGet("GetEmployeeList")] + public IActionResult GetEmployeeList(string? search = "") + { + search ??= ""; + + var data = _db.Employees + .Include(e => e.JobTitle) + .Include(e => e.Emails) + .Include(e => e.Phones) + .Where(e => !e.IsDeleted.HasValue || e.IsDeleted == false) + .Select(e => new EmployeeListItem_DTO + { + Id = e.Id, + Name = e.FirstName + " " + e.LastName, + JobTitle = e.JobTitle != null ? e.JobTitle.Name : "", + Role = "", + Email = e.Emails.Where(x => x.IsPrimary == true).Select(x => x.Address).FirstOrDefault(), + Phone = e.Phones.Where(x => x.IsPrimary == true) + .Select(x => x.Number + (x.Extension != null ? " ext. " + x.Extension : "")) + .FirstOrDefault(), + Status = e.Status, + LastLogin = e.LastLogin + }) + .ToList(); + + return Ok(data); + } + // ----------------------------------- + // GET: api/Employee/DeleteEmployees?id=5 + // ----------------------------------- + [HttpGet("DeleteEmployees")] + public async Task DeleteEmployees(int id) + { + try + { + var employee = await _db.Employees + .FirstOrDefaultAsync(e => e.Id == id); + + if (employee == null) + return BadRequest(new Response + { + Status = "Error", + Message = "Employee not found." + }); + + _db.Employees.Remove(employee); + await _db.SaveChangesAsync(); + + return Ok(new DataResponse + { + Message = "Employee deleted successfully.", + Status = "200" + }); + } + catch (Exception ex) + { + return BadRequest(new Response + { + Status = "Error", + Message = ex.Message + }); + } + } + +} diff --git a/Api.SeaHavenIndustries/Controllers/FollowUpController.cs b/Api.SeaHavenIndustries/Controllers/FollowUpController.cs new file mode 100644 index 0000000..ef819bc --- /dev/null +++ b/Api.SeaHavenIndustries/Controllers/FollowUpController.cs @@ -0,0 +1,148 @@ +using Api.SeaHavenIndustries.DTOs; +using Data.SeaHavenIndustries; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +[ApiController] +[Route("api/FollowUp")] +public class FollowUpController : ControllerBase +{ + private readonly ApplicationDbContext _db; + + public FollowUpController(ApplicationDbContext db) + { + _db = db; + } + + [HttpGet("GetFollowUpList")] + public IActionResult GetFollowUps( + string? search = "", + bool completed = false, + int page = 1, + int pageSize = 12) + { + var status = completed ? "Completed" : "Open"; + + var query = _db.FollowUps + .Include(x => x.Employee) + .Include(x => x.Account) + .Include(x => x.Location) + .Include(x => x.WorkOrder) + .Where(x => x.Status == status); + + if (!string.IsNullOrWhiteSpace(search)) + { + search = search.ToLower(); + + query = query.Where(x => + (x.Reason ?? "").ToLower().Contains(search) || + (x.Account != null && (x.Account.Name ?? "").ToLower().Contains(search)) || + (x.Employee != null && + ( + ((x.Employee.FirstName ?? "") + " " + (x.Employee.LastName ?? "")) + .ToLower() + .Contains(search) + ) + ) + ); + } + + var totalCount = query.Count(); + + var data = query + .OrderByDescending(x => x.Id) + .Skip((page - 1) * pageSize) + .Take(pageSize) + .Select(x => new + { + x.Id, + x.Reason, + x.ScheduleDate, + Account = x.Account != null ? x.Account.Name : "", + AssignedTo = x.Employee != null + ? (x.Employee.FirstName + " " + x.Employee.LastName) + : "", + LocationName = x.Location != null ? x.Location.Name : "", + WorkOrderNumber = x.WorkOrder != null ? x.WorkOrder.WorkerOrderNumber : "", + x.Status + }) + .ToList(); + + return Ok(new Pagination_DTO + { + Data = data, + PageNumber = page, + PageSize = pageSize, + TotalCount = totalCount, + TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize) + }); + } + + + [HttpPost("Create")] + public async Task Create(FollowUp_DTO dto) + { + var model = new FollowUps + { + Reason = dto.Reason, + ScheduleDate = dto.ScheduleDate, + ScheduleStartTime = dto.ScheduleStartTime, + EmployeeId = dto.EmployeeId, + WorkOrderId = dto.WorkOrderId, + AccountId = dto.AccountId, + LocationId = dto.LocationId, + Status = "Open", + CreatedDate = DateTime.UtcNow + }; + + _db.FollowUps.Add(model); + await _db.SaveChangesAsync(); + + return Ok(new DataResponse { Status = "200", Message = "Follow Up created" }); + } + + [HttpPost("Update")] + public async Task Update(FollowUp_DTO dto) + { + var model = await _db.FollowUps.FindAsync(dto.Id); + if (model == null) return NotFound(); + + model.Reason = dto.Reason; + model.ScheduleDate = dto.ScheduleDate; + model.ScheduleStartTime = dto.ScheduleStartTime; + model.EmployeeId = dto.EmployeeId; + model.WorkOrderId = dto.WorkOrderId; + model.AccountId = dto.AccountId; + model.LocationId = dto.LocationId; + model.LastModificationTime = DateTime.UtcNow; + + await _db.SaveChangesAsync(); + return Ok(new DataResponse { Status = "200", Message = "Follow Up updated" }); + } + + [HttpPost("Complete")] + public async Task Complete(int id) + { + var model = await _db.FollowUps.FindAsync(id); + if (model == null) return NotFound(); + + model.Status = "Completed"; + model.LastModificationTime = DateTime.UtcNow; + await _db.SaveChangesAsync(); + + return Ok(); + } + + [HttpPost("Cancel")] + public async Task Cancel(int id) + { + var model = await _db.FollowUps.FindAsync(id); + if (model == null) return NotFound(); + + model.Status = "Cancelled"; + model.LastModificationTime = DateTime.UtcNow; + await _db.SaveChangesAsync(); + + return Ok(); + } +} diff --git a/Api.SeaHavenIndustries/Controllers/PMScheduleController.cs b/Api.SeaHavenIndustries/Controllers/PMScheduleController.cs new file mode 100644 index 0000000..5d60530 --- /dev/null +++ b/Api.SeaHavenIndustries/Controllers/PMScheduleController.cs @@ -0,0 +1,69 @@ +using Api.SeaHavenIndustries.DTOs; +using Data.SeaHavenIndustries; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +[ApiController] +[Route("api/PMSchedule")] +public class PMScheduleController : ControllerBase +{ + private readonly ApplicationDbContext _db; + + public PMScheduleController(ApplicationDbContext db) + { + _db = db; + } + + [HttpGet("GetList")] + public IActionResult GetList() + { + var data = _db.PMSchedules + .Include(x => x.Asset) + .Include(x => x.Location) + .OrderByDescending(x => x.Id) + .Select(x => new + { + x.Id, + x.Name, + x.Frequency, + x.StartDate, + x.IsActive, + Asset = x.Asset != null ? x.Asset.Name : null, + Location = x.Location != null ? x.Location.Name : null + }) + .ToList(); + + return Ok(data); + } + + [HttpPost("Save")] + public async Task Save(PMSchedule_DTO dto) + { + PMSchedules model; + + if (dto.Id == 0) + { + model = new PMSchedules + { + CreatedDate = DateTime.UtcNow + }; + _db.PMSchedules.Add(model); + } + else + { + model = await _db.PMSchedules.FindAsync(dto.Id); + if (model == null) return NotFound(); + model.LastModificationTime = DateTime.UtcNow; + } + + model.Name = dto.Name; + model.Frequency = dto.Frequency; + model.StartDate = dto.StartDate; + model.IsActive = dto.IsActive; + model.AssetId = dto.AssetId; + model.LocationId = dto.LocationId; + + await _db.SaveChangesAsync(); + return Ok(); + } +} diff --git a/Api.SeaHavenIndustries/DTOs/Account_DTO.cs b/Api.SeaHavenIndustries/DTOs/Account_DTO.cs new file mode 100644 index 0000000..11c496c --- /dev/null +++ b/Api.SeaHavenIndustries/DTOs/Account_DTO.cs @@ -0,0 +1,30 @@ +namespace Api.SeaHavenIndustries.DTOs +{ + public class Account_DTO + { + public string? Name { get; set; } + public string? Type { get; set; } + public int? Importance { get; set; } + public int? TerritoryId { get; set; } + public int? OwnerEmployeeId { get; set; } + public string? PrivacySetting { get; set; } + public string? About { get; set; } + public string? Tags { get; set; } + + public string? Phone { get; set; } + public string? Email { get; set; } + public int? IndustryId { get; set; } + public string? TimeZone { get; set; } + public string? Website { get; set; } + public string? CurrencyCode { get; set; } + public string? ServiceInstructions { get; set; } + + public string? FacebookUrl { get; set; } + public string? LinkedInUrl { get; set; } + public string? TwitterUrl { get; set; } + } + public class EditAccount_DTO : Account_DTO + { + public int Id { get; set; } + } +} diff --git a/Api.SeaHavenIndustries/DTOs/Employee_DTO.cs b/Api.SeaHavenIndustries/DTOs/Employee_DTO.cs new file mode 100644 index 0000000..f0c27c1 --- /dev/null +++ b/Api.SeaHavenIndustries/DTOs/Employee_DTO.cs @@ -0,0 +1,35 @@ +namespace Api.SeaHavenIndustries.DTOs +{ + public class AddEmployee_DTO + { + public string FirstName { get; set; } = null!; + public string LastName { get; set; } = null!; + + public int? JobTitleId { get; set; } + public int? PermissionGroupId { get; set; } + + public string? Email { get; set; } + public string? Phone { get; set; } + public string? PhoneExtension { get; set; } + + public string? Status { get; set; } + public DateTime? LastLogin { get; set; } + } + + public class EditEmployee_DTO : AddEmployee_DTO + { + public int Id { get; set; } + } + + public class EmployeeListItem_DTO + { + public int Id { get; set; } + public string Name { get; set; } = ""; + public string JobTitle { get; set; } = ""; + public string Role { get; set; } = ""; + public string? Email { get; set; } + public string? Phone { get; set; } + public string? Status { get; set; } + public DateTime? LastLogin { get; set; } + } +} diff --git a/Api.SeaHavenIndustries/DTOs/FollowUp_DTO.cs b/Api.SeaHavenIndustries/DTOs/FollowUp_DTO.cs new file mode 100644 index 0000000..4180160 --- /dev/null +++ b/Api.SeaHavenIndustries/DTOs/FollowUp_DTO.cs @@ -0,0 +1,17 @@ +namespace Api.SeaHavenIndustries.DTOs +{ + public class FollowUp_DTO + { + public int Id { get; set; } + + public string Reason { get; set; } = null!; + + public DateTime ScheduleDate { get; set; } + public TimeSpan ScheduleStartTime { get; set; } + + public int? EmployeeId { get; set; } + public int? WorkOrderId { get; set; } + public int? AccountId { get; set; } + public int? LocationId { get; set; } + } +} diff --git a/Api.SeaHavenIndustries/DTOs/PMSchedule_DTO.cs b/Api.SeaHavenIndustries/DTOs/PMSchedule_DTO.cs new file mode 100644 index 0000000..5381625 --- /dev/null +++ b/Api.SeaHavenIndustries/DTOs/PMSchedule_DTO.cs @@ -0,0 +1,13 @@ +namespace Api.SeaHavenIndustries.DTOs +{ + public class PMSchedule_DTO + { + public int Id { get; set; } + public string Name { get; set; } = null!; + public string Frequency { get; set; } = null!; + public DateTime StartDate { get; set; } + public bool IsActive { get; set; } + public int? AssetId { get; set; } + public int? LocationId { get; set; } + } +} diff --git a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs index e1938ad..f25ac92 100644 --- a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs +++ b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs @@ -30,13 +30,22 @@ namespace Data.SeaHavenIndustries public DbSet Contacts { get; set; } public DbSet workOrders { get; set; } public DbSet