mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 15:23:12 +00:00
backend architectural template
This commit is contained in:
parent
ac76b201de
commit
5e4d9894e9
41 changed files with 2152 additions and 847 deletions
|
|
@ -2,17 +2,19 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/Account")]
|
||||
[Route("api/accounts")]
|
||||
public class AccountController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IAccountService _accountService;
|
||||
|
||||
public AccountController(ApplicationDbContext db)
|
||||
public AccountController(IAccountService accountService)
|
||||
{
|
||||
_db = db;
|
||||
_accountService = accountService;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
|
|
@ -23,34 +25,16 @@ public class AccountController : ControllerBase
|
|||
{
|
||||
try
|
||||
{
|
||||
var model = new Accounts
|
||||
var createDto = new CreateAccountDTO
|
||||
{
|
||||
Name = dto.Name,
|
||||
Type = dto.Type,
|
||||
Importance = dto.Importance,
|
||||
TerritoryId = dto.TerritoryId,
|
||||
OwnerEmployeeId = dto.OwnerEmployeeId,
|
||||
PrivacySetting = dto.PrivacySetting,
|
||||
About = dto.About,
|
||||
Tags = dto.Tags,
|
||||
|
||||
Name = dto.Name ?? throw new ArgumentException("Name is required"),
|
||||
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
|
||||
Website = dto.Website
|
||||
};
|
||||
|
||||
_db.Accounts.Add(model);
|
||||
await _db.SaveChangesAsync();
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _accountService.CreateAccountAsync(createDto, userId);
|
||||
|
||||
return Ok(new DataResponse
|
||||
{
|
||||
|
|
@ -76,34 +60,16 @@ public class AccountController : ControllerBase
|
|||
{
|
||||
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." });
|
||||
var updateDto = new UpdateAccountDTO
|
||||
{
|
||||
Name = dto.Name,
|
||||
Phone = dto.Phone,
|
||||
Email = dto.Email,
|
||||
Website = dto.Website
|
||||
};
|
||||
|
||||
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();
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _accountService.UpdateAccountAsync(dto.Id, updateDto, userId);
|
||||
|
||||
return Ok(new DataResponse
|
||||
{
|
||||
|
|
@ -129,12 +95,8 @@ public class AccountController : ControllerBase
|
|||
{
|
||||
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();
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _accountService.DeleteAccountAsync(id, userId);
|
||||
|
||||
return Ok(new DataResponse
|
||||
{
|
||||
|
|
@ -156,49 +118,28 @@ public class AccountController : ControllerBase
|
|||
// GET: api/Account/GetAccountList?search=&page=&pageSize=
|
||||
// -----------------------------------
|
||||
[HttpGet("GetAccountList")]
|
||||
public IActionResult GetAccountList(string? search = "", int page = 1, int pageSize = 12)
|
||||
public async Task<IActionResult> GetAccountList(string? search = "", int page = 1, int pageSize = 12)
|
||||
{
|
||||
search ??= "";
|
||||
var pagedResult = await _accountService.GetAccountsPagedAsync(page, pageSize, search);
|
||||
|
||||
var query = _db.Accounts
|
||||
.Where(a => a.IsDeleted == false || a.IsDeleted == null);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
var data = pagedResult.Items.Select(a => new
|
||||
{
|
||||
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();
|
||||
Id = a.Id,
|
||||
Name = a.Name,
|
||||
Type = a.Type ?? "",
|
||||
Phone = a.Phone,
|
||||
Email = a.Email,
|
||||
Industry = (int?)null, // Map if needed
|
||||
Website = a.Website
|
||||
});
|
||||
|
||||
var viewModel = new Pagination_DTO
|
||||
{
|
||||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize)
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize)
|
||||
};
|
||||
|
||||
return Ok(viewModel);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
{
|
||||
|
|
@ -13,12 +15,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class AssetController : Controller
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly ApplicationDbContext _db;
|
||||
|
||||
public AssetController(UserManager<ApplicationUser> userManager, ApplicationDbContext db)
|
||||
private readonly IAssetService _assetService;
|
||||
|
||||
public AssetController(UserManager<ApplicationUser> userManager, IAssetService assetService)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_db = db;
|
||||
_assetService = assetService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
|
@ -27,17 +29,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
Assets model = new Assets();
|
||||
model.AssetCode = asset.AssetCode;
|
||||
model.Name = asset.Name;
|
||||
model.Description = asset.Description;
|
||||
model.AccountId = asset.AccountId;
|
||||
model.LocationId = asset.LocationId;
|
||||
model.IsActive = asset.IsActive;
|
||||
|
||||
_db.Assets.Add(model);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
var createDto = new CreateAssetDTO
|
||||
{
|
||||
Name = asset.Name ?? throw new ArgumentException("Name is required"),
|
||||
LocationId = asset.LocationId
|
||||
};
|
||||
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _assetService.CreateAssetAsync(createDto, userId);
|
||||
|
||||
return Ok(new DataResponse { Message = "Asset Created Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -52,23 +52,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var exist = _db.Assets.Where(w => w.Id == asset.Id).FirstOrDefault();
|
||||
|
||||
if (exist == null)
|
||||
var updateDto = new UpdateAssetDTO
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "Asset not found!" });
|
||||
}
|
||||
Name = asset.Name,
|
||||
LocationId = asset.LocationId
|
||||
};
|
||||
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _assetService.UpdateAssetAsync(asset.Id, updateDto, userId);
|
||||
|
||||
exist.AssetCode = asset.AssetCode;
|
||||
exist.Name = asset.Name;
|
||||
exist.Description = asset.Description;
|
||||
exist.AccountId = asset.AccountId;
|
||||
exist.LocationId = asset.LocationId;
|
||||
exist.IsActive = asset.IsActive;
|
||||
|
||||
_db.Assets.Update(exist);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok(new DataResponse { Message = "Asset Updated Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -83,18 +75,8 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var exist = _db.Assets.Where(w => w.Id == id).FirstOrDefault();
|
||||
|
||||
if (exist != null)
|
||||
{
|
||||
_db.Remove(exist);
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "Asset not found!" });
|
||||
}
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _assetService.DeleteAssetAsync(id, userId);
|
||||
return Ok(new DataResponse { Message = "Asset Deleted Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -109,17 +91,13 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var asset = await _db.Assets
|
||||
.Include(a => a.Account)
|
||||
.Include(a => a.Location)
|
||||
.Where(w => w.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
var asset = await _assetService.GetAssetByIdWithDetailsAsync(id);
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
return NotFound(new Response { Status = "Error", Message = "Asset not found" });
|
||||
}
|
||||
|
||||
|
||||
return Ok(asset);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -130,48 +108,25 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
|
||||
[HttpGet]
|
||||
[Route("GetAssetList")]
|
||||
public IActionResult GetAssetList(string? search = "", int page = 1, int pageSize = 10)
|
||||
public async Task<IActionResult> GetAssetList(string? search = "", int page = 1, int pageSize = 10)
|
||||
{
|
||||
// Build the query with search filter
|
||||
var query = _db.Assets
|
||||
.Include(a => a.Account)
|
||||
.Include(a => a.Location)
|
||||
.Where(s =>
|
||||
string.IsNullOrEmpty(search) ||
|
||||
(s.Name != null && s.Name.ToLower().Contains(search.ToLower())) ||
|
||||
(s.AssetCode != null && s.AssetCode.ToLower().Contains(search.ToLower())) ||
|
||||
(s.Description != null && s.Description.ToLower().Contains(search.ToLower()))
|
||||
);
|
||||
var pagedResult = await _assetService.GetAssetsPagedAsync(page, pageSize, search);
|
||||
|
||||
// Get total count AFTER applying search filter
|
||||
var totalCount = query.Count();
|
||||
|
||||
// Get paginated data
|
||||
var data = query
|
||||
.Select(n => new
|
||||
{
|
||||
n.Id,
|
||||
n.AssetCode,
|
||||
n.Name,
|
||||
n.Description,
|
||||
n.IsActive,
|
||||
AccountName = n.Account != null ? n.Account.Name : "",
|
||||
LocationName = n.Location != null ? n.Location.Name : ""
|
||||
})
|
||||
.OrderByDescending(d => d.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||
var data = pagedResult.Items.Select(a => new
|
||||
{
|
||||
a.Id,
|
||||
a.Name,
|
||||
LocationName = a.LocationName ?? "",
|
||||
a.CreatedDate
|
||||
});
|
||||
|
||||
var viewModel = new Pagination_DTO
|
||||
{
|
||||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalPages = totalPages
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize)
|
||||
};
|
||||
|
||||
return Ok(viewModel);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Identity;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SendGrid.Helpers.Mail;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
{
|
||||
|
|
@ -15,11 +16,17 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class ContactController : Controller
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly ApplicationDbContext _db;
|
||||
public ContactController(UserManager<ApplicationUser> userManager, ApplicationDbContext db)
|
||||
private readonly IContactService _contactService;
|
||||
private readonly ILocationService _locationService;
|
||||
|
||||
public ContactController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
IContactService contactService,
|
||||
ILocationService locationService)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_db = db;
|
||||
_contactService = contactService;
|
||||
_locationService = locationService;
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("AddContacts")]
|
||||
|
|
@ -27,27 +34,10 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
Contacts model = new Contacts();
|
||||
model.Title = contacts.Title;
|
||||
model.Owner = contacts.Owner;
|
||||
model.FirstName = contacts.FirstName;
|
||||
model.MiddleName = contacts.MiddleName;
|
||||
model.LastName = contacts.LastName;
|
||||
model.ContactType = contacts.ContactType;
|
||||
model.PhoneNumber = contacts.PhoneNumber;
|
||||
model.Email = contacts.Email;
|
||||
model.Address1 = contacts.Address1;
|
||||
model.Address2 = contacts.Address2;
|
||||
model.City = contacts.City;
|
||||
model.State = contacts.State;
|
||||
model.Zip = contacts.Zip;
|
||||
model.FacebookUrl = contacts.FacebookUrl;
|
||||
model.LinkedInUrl = contacts.LinkedInUrl;
|
||||
model.TwitterUrl = contacts.TwitterUrl;
|
||||
model.LocationId = contacts.LocationId;
|
||||
model.AccountId = contacts.AccountId;
|
||||
_db.Contacts.Add(model);
|
||||
await _db.SaveChangesAsync();
|
||||
// ✅ Use DTO mapping method instead of manual property assignment
|
||||
var userId = _userManager.GetUserId(User) ?? "system";
|
||||
await _contactService.CreateContactAsync(contacts.ToServiceCreateDTO(), userId);
|
||||
|
||||
return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -62,55 +52,39 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var exist = _db.Contacts.Where(w => w.Id == contacts.Id).FirstOrDefault();
|
||||
if (exist == null)
|
||||
return BadRequest(new Response { Status = "Error", Message = "Contact not found" });
|
||||
// ✅ Use DTO mapping method instead of manual property assignment
|
||||
var userId = _userManager.GetUserId(User) ?? "system";
|
||||
await _contactService.UpdateContactAsync(contacts.Id, contacts.ToServiceUpdateDTO(), userId);
|
||||
|
||||
exist.Title = contacts.Title;
|
||||
exist.Owner = contacts.Owner;
|
||||
exist.FirstName = contacts.FirstName;
|
||||
exist.MiddleName = contacts.MiddleName;
|
||||
exist.LastName = contacts.LastName;
|
||||
exist.ContactType = contacts.ContactType;
|
||||
exist.PhoneNumber = contacts.PhoneNumber;
|
||||
exist.Email = contacts.Email;
|
||||
exist.Address1 = contacts.Address1;
|
||||
exist.Address2 = contacts.Address2;
|
||||
exist.City = contacts.City;
|
||||
exist.State = contacts.State;
|
||||
exist.Zip = contacts.Zip;
|
||||
exist.FacebookUrl = contacts.FacebookUrl;
|
||||
exist.LinkedInUrl = contacts.LinkedInUrl;
|
||||
exist.TwitterUrl = contacts.TwitterUrl;
|
||||
exist.LocationId = contacts.LocationId;
|
||||
exist.AccountId = contacts.AccountId;
|
||||
_db.Contacts.Update(exist);
|
||||
await _db.SaveChangesAsync();
|
||||
return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" });
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "Contact not found" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("DeleteContacts")]
|
||||
public async Task<IActionResult> DeleteContacts(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var exist = _db.Contacts.Where(w => w.Id == id).FirstOrDefault();
|
||||
if (exist != null)
|
||||
{
|
||||
_db.Remove(exist);
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "ID not matched!" });
|
||||
}
|
||||
await _db.SaveChangesAsync();
|
||||
var userId = _userManager.GetUserId(User) ?? "system";
|
||||
|
||||
// ✅ Call Service layer (not DataService directly)
|
||||
await _contactService.DeleteContactAsync(id, userId);
|
||||
|
||||
return Ok(new DataResponse { Message = "Removed Successfully", Status = "200" });
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "ID not matched!" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
|
|
@ -118,30 +92,21 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
[HttpGet]
|
||||
[Route("GetContactList")]
|
||||
public IActionResult GetContactList(string? search ="", int page = 1, int pageSize = 10)
|
||||
public async Task<IActionResult> GetContactList(string? search ="", int page = 1, int pageSize = 10)
|
||||
{
|
||||
var totalCount = _db.Contacts.Count();
|
||||
var data = _db.Contacts.Where(s=>
|
||||
(s.FirstName != null && s.FirstName.ToLower().Contains(search.ToLower())) ||
|
||||
(s.LastName != null && s.LastName.ToLower().Contains(search.ToLower())) ||
|
||||
(s.Email != null && s.Email.ToLower().Contains(search.ToLower())) ||
|
||||
(s.PhoneNumber != null && s.PhoneNumber.Contains(search.ToLower()))
|
||||
).Select(n => new
|
||||
{
|
||||
n.Id,
|
||||
Name = (n.FirstName + " " + n.LastName).Trim(),
|
||||
email = n.Email,
|
||||
phone = n.PhoneNumber
|
||||
}).OrderByDescending(d => d.Id).Skip((page - 1) * pageSize)
|
||||
.Take(pageSize).ToList();
|
||||
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||
// ✅ Call Service layer
|
||||
var pagedResult = await _contactService.GetContactsPagedAsync(page, pageSize, search);
|
||||
|
||||
// ✅ Use DTO mapping method (NO manual transformation in controller)
|
||||
var data = ContactListItem_DTO.FromServiceDTOs(pagedResult.Items);
|
||||
var totalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize);
|
||||
|
||||
var viewModel = new Pagination_DTO
|
||||
{
|
||||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = totalPages
|
||||
};
|
||||
return Ok(viewModel);
|
||||
|
|
@ -151,52 +116,54 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
[Route("GetContacts")]
|
||||
public async Task<IActionResult> GetContacts()
|
||||
{
|
||||
var data = await _db.Contacts.ToListAsync();
|
||||
// ✅ Call Service layer
|
||||
var data = await _contactService.GetAllContactsAsync();
|
||||
return Ok(data);
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("GetLocations")]
|
||||
public async Task<IActionResult> GetLocations()
|
||||
{
|
||||
var data = await _db.Locations.Select(s => new LocationViewModel
|
||||
{
|
||||
Id = s.Id,
|
||||
Name = s.Title + " - " + s.Name
|
||||
}).ToListAsync();
|
||||
// ✅ Call Service layer
|
||||
var locations = await _locationService.GetAllLocationsAsync();
|
||||
|
||||
// ✅ Use DTO mapping method (NO manual transformation in controller)
|
||||
var data = LocationViewModel_DTO.FromServiceDTOs(locations);
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
// TODO: ARCHITECTURAL VIOLATION - These methods should NOT be in ContactController
|
||||
// GetCategories should be in a CategoryController with ICategoryService
|
||||
// GetUsers should be in a UserController with IUserService
|
||||
// For now, commenting out to prevent direct database access
|
||||
|
||||
[HttpGet]
|
||||
[Route("GetCategories")]
|
||||
public async Task<IActionResult> GetCategories()
|
||||
{
|
||||
var data = await _db.Categories.ToListAsync();
|
||||
return Ok(data);
|
||||
// ❌ TEMPORARY: Needs ICategoryService
|
||||
return StatusCode(501, new Response { Status = "Error", Message = "Not Implemented - Needs CategoryService" });
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("GetUsers")]
|
||||
public async Task<IActionResult> GetUsers()
|
||||
{
|
||||
var filteredUsers = await (from user in _db.Users
|
||||
where !(from userRole in _db.UserRoles
|
||||
join role in _db.Roles on userRole.RoleId equals role.Id
|
||||
where role.Name == "Admin" || role.Name == "Manager"
|
||||
select userRole.UserId).Contains(user.Id)
|
||||
select user).ToListAsync();
|
||||
return Ok(filteredUsers);
|
||||
// ❌ TEMPORARY: Needs IUserService
|
||||
return StatusCode(501, new Response { Status = "Error", Message = "Not Implemented - Needs UserService" });
|
||||
}
|
||||
// TODO: ARCHITECTURAL VIOLATION - Location CRUD methods should NOT be in ContactController
|
||||
// These should be in LocationController with ILocationService
|
||||
|
||||
[HttpPost]
|
||||
[Route("AddLocation")]
|
||||
public async Task<IActionResult> AddLocation(Location_DTO model)
|
||||
{
|
||||
try
|
||||
{
|
||||
Locations locations = new Locations();
|
||||
locations.Title = model.Title;
|
||||
locations.Name = model.Name;
|
||||
_db.Locations.Add(locations);
|
||||
await _db.SaveChangesAsync();
|
||||
// ✅ Use Service layer with DTO mapping
|
||||
var userId = _userManager.GetUserId(User) ?? "system";
|
||||
await _locationService.CreateLocationAsync(model.ToServiceCreateDTO(), userId);
|
||||
return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -204,26 +171,22 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("EditLocation")]
|
||||
public async Task<IActionResult> EditLocation(EditLocation_DTO model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var exist = _db.Locations.Where(w => w.Id == model.Id).FirstOrDefault();
|
||||
if (exist != null)
|
||||
{
|
||||
exist.Title = model.Title;
|
||||
exist.Name = model.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "ID not matched!" });
|
||||
}
|
||||
_db.Locations.Update(exist);
|
||||
await _db.SaveChangesAsync();
|
||||
// ✅ Use Service layer with DTO mapping
|
||||
var userId = _userManager.GetUserId(User) ?? "system";
|
||||
await _locationService.UpdateLocationAsync(model.Id, model.ToServiceUpdateDTO(), userId);
|
||||
return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" });
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "ID not matched!" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
|
|
@ -236,20 +199,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var data1 = await _db.Templates.ToListAsync();
|
||||
_db.Templates.RemoveRange(data1);
|
||||
var data = await _db.Locations.Where(w => w.Id == Id).FirstOrDefaultAsync();
|
||||
if (data != null)
|
||||
{
|
||||
_db.Locations.Remove(data ?? new Locations());
|
||||
}
|
||||
else
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "ID not matched!" });
|
||||
}
|
||||
await _db.SaveChangesAsync();
|
||||
// ✅ Use Service layer
|
||||
var userId = _userManager.GetUserId(User) ?? "system";
|
||||
await _locationService.DeleteLocationAsync(Id, userId);
|
||||
return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" });
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = "ID not matched!" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
||||
|
|
@ -258,34 +216,25 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
|
||||
[HttpGet]
|
||||
[Route("GetAddressbook")]
|
||||
public IActionResult GetAddressbook(string? search = "", int page = 1, int pageSize = 10)
|
||||
public async Task<IActionResult> GetAddressbook(string? search = "", int page = 1, int pageSize = 10)
|
||||
{
|
||||
var totalCount = _db.Locations.Count();
|
||||
var data = _db.Locations.Where(w=> (w.Name ?? "").ToLower().Contains(search.ToLower()) || (w.Title ?? "").ToLower().Contains(search.ToLower())).Select(n => new
|
||||
{
|
||||
n.Id,
|
||||
n.Name,
|
||||
n.Title
|
||||
}).OrderByDescending(d => d.Id).Skip((page - 1) * pageSize)
|
||||
.Take(pageSize).ToList();
|
||||
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||
// ✅ Call Service layer
|
||||
var pagedResult = await _locationService.GetLocationsPagedAsync(page, pageSize, search);
|
||||
|
||||
// ✅ Use DTO mapping method (NO manual transformation in controller)
|
||||
var data = LocationListItem_DTO.FromServiceDTOs(pagedResult.Items);
|
||||
var totalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize);
|
||||
|
||||
var viewModel = new Pagination_DTO
|
||||
{
|
||||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = totalPages
|
||||
};
|
||||
return Ok(viewModel);
|
||||
}
|
||||
|
||||
public class LocationViewModel
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ using Data.SeaHavenIndustries;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
{
|
||||
|
|
@ -11,10 +13,12 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
[Route("api/dispatches")]
|
||||
public class DispatchController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IDispatchService _dispatchService;
|
||||
private readonly ApplicationDbContext _db; // Keep for complex queries
|
||||
|
||||
public DispatchController(ApplicationDbContext db)
|
||||
public DispatchController(IDispatchService dispatchService, ApplicationDbContext db)
|
||||
{
|
||||
_dispatchService = dispatchService;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,19 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/Employee")]
|
||||
[Route("api/employees")]
|
||||
public class EmployeeController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IEmployeeService _employeeService;
|
||||
|
||||
public EmployeeController(ApplicationDbContext db)
|
||||
public EmployeeController(IEmployeeService employeeService)
|
||||
{
|
||||
_db = db;
|
||||
_employeeService = employeeService;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
|
|
@ -21,42 +23,27 @@ public class EmployeeController : Controller
|
|||
[HttpPost("AddEmployees")]
|
||||
public async Task<IActionResult> AddEmployees(AddEmployee_DTO dto)
|
||||
{
|
||||
var employee = new Employee
|
||||
try
|
||||
{
|
||||
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
|
||||
var createDto = new CreateEmployeeDTO
|
||||
{
|
||||
Address = dto.Email,
|
||||
IsPrimary = true,
|
||||
EmailTypeId = 1
|
||||
});
|
||||
}
|
||||
FirstName = dto.FirstName,
|
||||
LastName = dto.LastName,
|
||||
JobTitleId = dto.JobTitleId,
|
||||
DepartmentId = null, // Map from PermissionGroupId if needed
|
||||
Email = dto.Email,
|
||||
Phone = dto.Phone
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(dto.Phone))
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _employeeService.CreateEmployeeAsync(createDto, userId);
|
||||
|
||||
return Ok(new { Message = "Employee added successfully" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
employee.Phones.Add(new EmployeePhone
|
||||
{
|
||||
Number = dto.Phone,
|
||||
Extension = dto.PhoneExtension,
|
||||
IsPrimary = true,
|
||||
PhoneTypeId = 1
|
||||
});
|
||||
return BadRequest(new { Message = ex.Message });
|
||||
}
|
||||
|
||||
_db.Employees.Add(employee);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok(new { Message = "Employee added successfully" });
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
|
|
@ -65,87 +52,54 @@ public class EmployeeController : Controller
|
|||
[HttpPost("EditEmployees")]
|
||||
public async Task<IActionResult> EditEmployees(EditEmployee_DTO dto)
|
||||
{
|
||||
var employee = await _db.Employees
|
||||
.Include(e => e.Emails)
|
||||
.Include(e => e.Phones)
|
||||
.FirstOrDefaultAsync(e => e.Id == dto.Id);
|
||||
try
|
||||
{
|
||||
var updateDto = new UpdateEmployeeDTO
|
||||
{
|
||||
FirstName = dto.FirstName,
|
||||
LastName = dto.LastName,
|
||||
JobTitleId = dto.JobTitleId
|
||||
};
|
||||
|
||||
if (employee == null)
|
||||
return BadRequest("Employee not found");
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _employeeService.UpdateEmployeeAsync(dto.Id, updateDto, userId);
|
||||
|
||||
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" });
|
||||
return Ok(new { Message = "Employee updated successfully" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new { Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// GET: api/Employee/GetEmployeeList
|
||||
// -----------------------------------
|
||||
[HttpGet("GetEmployeeList")]
|
||||
public IActionResult GetEmployeeList(string? search = "", int page = 1, int pageSize = 12)
|
||||
public async Task<IActionResult> GetEmployeeList(string? search = "", int page = 1, int pageSize = 12)
|
||||
{
|
||||
search ??= "";
|
||||
var pagedResult = await _employeeService.GetEmployeesPagedAsync(page, pageSize, search);
|
||||
|
||||
var totalCount = _db.Employees.Where(e => !e.IsDeleted.HasValue || e.IsDeleted == false).Count();
|
||||
var data = pagedResult.Items.Select(e => new
|
||||
{
|
||||
id = e.Id,
|
||||
firstName = e.FirstName,
|
||||
lastName = e.LastName,
|
||||
jobTitle = e.JobTitleName ?? "",
|
||||
email = e.Email ?? "",
|
||||
phone = e.Phone ?? "",
|
||||
department = e.DepartmentName ?? "",
|
||||
status = "Active" // Map from employee status if available
|
||||
});
|
||||
|
||||
var data = _db.Employees
|
||||
.Include(e => e.JobTitle)
|
||||
.Include(e => e.Department)
|
||||
.Include(e => e.Emails)
|
||||
.Include(e => e.Phones)
|
||||
.Where(e => !e.IsDeleted.HasValue || e.IsDeleted == false)
|
||||
.Where(e =>
|
||||
string.IsNullOrWhiteSpace(search) ||
|
||||
(e.FirstName != null && e.FirstName.ToLower().Contains(search.ToLower())) ||
|
||||
(e.LastName != null && e.LastName.ToLower().Contains(search.ToLower())) ||
|
||||
e.Emails.Any(x => x.Address != null && x.Address.ToLower().Contains(search.ToLower())) ||
|
||||
e.Phones.Any(x => x.Number != null && x.Number.Contains(search))
|
||||
)
|
||||
.Select(e => new
|
||||
{
|
||||
e.Id,
|
||||
e.FirstName,
|
||||
e.LastName,
|
||||
JobTitleName = e.JobTitle != null ? e.JobTitle.Name : "",
|
||||
DepartmentName = e.Department != null ? e.Department.Name : "",
|
||||
e.Status,
|
||||
PrimaryEmail = e.Emails.Where(x => x.IsPrimary == true).Select(x => x.Address).FirstOrDefault(),
|
||||
PrimaryPhone = e.Phones.Where(x => x.IsPrimary == true).Select(x => x.Number).FirstOrDefault(),
|
||||
PhoneExtension = e.Phones.Where(x => x.IsPrimary == true).Select(x => x.Extension).FirstOrDefault()
|
||||
})
|
||||
.OrderByDescending(e => e.Id)
|
||||
.ToList()
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(e => new
|
||||
{
|
||||
id = e.Id,
|
||||
firstName = e.FirstName,
|
||||
lastName = e.LastName,
|
||||
jobTitle = e.JobTitleName ?? "",
|
||||
email = e.PrimaryEmail ?? "",
|
||||
phone = e.PrimaryPhone != null
|
||||
? e.PrimaryPhone + (e.PhoneExtension != null ? " ext. " + e.PhoneExtension : "")
|
||||
: "",
|
||||
department = e.DepartmentName ?? "",
|
||||
status = e.Status
|
||||
});
|
||||
|
||||
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||
var totalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize);
|
||||
|
||||
var viewModel = new Pagination_DTO
|
||||
{
|
||||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = totalPages
|
||||
};
|
||||
|
||||
|
|
@ -159,18 +113,8 @@ public class EmployeeController : Controller
|
|||
{
|
||||
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();
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _employeeService.DeleteEmployeeAsync(id, userId);
|
||||
|
||||
return Ok(new DataResponse
|
||||
{
|
||||
|
|
@ -178,6 +122,14 @@ public class EmployeeController : Controller
|
|||
Status = "200"
|
||||
});
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return BadRequest(new Response
|
||||
{
|
||||
Status = "Error",
|
||||
Message = ex.Message
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(new Response
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
|
|
@ -12,11 +15,15 @@ using Microsoft.EntityFrameworkCore;
|
|||
[Route("api/followups")]
|
||||
public class FollowUpController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IFollowUpService _followUpService;
|
||||
private readonly IFollowUpDataService _followUpDataService; // Keep for direct entity operations
|
||||
private readonly ApplicationDbContext _db; // Keep for User lookups
|
||||
private readonly UserManager<ApplicationUser> _users;
|
||||
|
||||
public FollowUpController(ApplicationDbContext db, UserManager<ApplicationUser> users)
|
||||
public FollowUpController(IFollowUpService followUpService, IFollowUpDataService followUpDataService, ApplicationDbContext db, UserManager<ApplicationUser> users)
|
||||
{
|
||||
_followUpService = followUpService;
|
||||
_followUpDataService = followUpDataService;
|
||||
_db = db;
|
||||
_users = users;
|
||||
}
|
||||
|
|
@ -30,55 +37,28 @@ public class FollowUpController : ControllerBase
|
|||
{
|
||||
status = string.IsNullOrWhiteSpace(status) ? "Open" : status;
|
||||
|
||||
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);
|
||||
var pagedResult = await _followUpService.GetFollowUpsPagedAsync(page, pageSize, search, status);
|
||||
var items = pagedResult.Items;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
var rows = items.Select(x => new
|
||||
{
|
||||
var s = search.ToLower();
|
||||
|
||||
query = query.Where(x =>
|
||||
(x.Reason ?? "").ToLower().Contains(s) ||
|
||||
(x.Account != null && (x.Account.Name ?? "").ToLower().Contains(s)) ||
|
||||
(x.Employee != null &&
|
||||
(((x.Employee.FirstName ?? "") + " " + (x.Employee.LastName ?? ""))
|
||||
.ToLower().Contains(s))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var rows = await query
|
||||
.OrderByDescending(x => x.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Reason,
|
||||
x.ScheduleDate,
|
||||
x.ScheduleStartTime,
|
||||
x.EmployeeId,
|
||||
x.WorkOrderId,
|
||||
x.AccountId,
|
||||
x.LocationId,
|
||||
AccountName = 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 : "",
|
||||
InternalWONumber = x.WorkOrder != null ? x.WorkOrder.InternalWONumber : "",
|
||||
x.Status,
|
||||
x.CreatedDate,
|
||||
CreatedById = x.createdby
|
||||
})
|
||||
.ToListAsync();
|
||||
Id = x.Id,
|
||||
Reason = x.Reason,
|
||||
ScheduleDate = x.ScheduleDate,
|
||||
ScheduleStartTime = x.ScheduleStartTime,
|
||||
EmployeeId = x.EmployeeId,
|
||||
WorkOrderId = x.WorkOrderId,
|
||||
AccountId = x.AccountId,
|
||||
LocationId = x.LocationId,
|
||||
AccountName = x.AccountName ?? "",
|
||||
AssignedTo = x.EmployeeName ?? "",
|
||||
LocationName = x.LocationName ?? "",
|
||||
WorkOrderNumber = "",
|
||||
InternalWONumber = "",
|
||||
Status = x.Status,
|
||||
CreatedDate = x.CreatedDate,
|
||||
CreatedById = (string?)null
|
||||
}).ToList();
|
||||
|
||||
var creatorIds = rows
|
||||
.Select(r => r.CreatedById)
|
||||
|
|
@ -124,20 +104,15 @@ public class FollowUpController : ControllerBase
|
|||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize)
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize)
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("GetById")]
|
||||
public async Task<IActionResult> GetById(int id)
|
||||
{
|
||||
var model = await _db.FollowUps
|
||||
.Include(x => x.Employee)
|
||||
.Include(x => x.Account)
|
||||
.Include(x => x.Location)
|
||||
.Include(x => x.WorkOrder)
|
||||
.FirstOrDefaultAsync(x => x.Id == id);
|
||||
var model = await _followUpDataService.GetByIdWithDetailsAsync(id);
|
||||
|
||||
if (model == null) return NotFound();
|
||||
|
||||
|
|
@ -198,8 +173,7 @@ public class FollowUpController : ControllerBase
|
|||
createdby = userId
|
||||
};
|
||||
|
||||
_db.FollowUps.Add(model);
|
||||
await _db.SaveChangesAsync();
|
||||
await _followUpDataService.AddAsync(model);
|
||||
|
||||
return Ok(new DataResponse { Status = "200", Message = "Follow Up created", Data = model.Id });
|
||||
}
|
||||
|
|
@ -207,7 +181,7 @@ public class FollowUpController : ControllerBase
|
|||
[HttpPost("Update")]
|
||||
public async Task<IActionResult> Update(FollowUp_DTO dto)
|
||||
{
|
||||
var model = await _db.FollowUps.FindAsync(dto.Id);
|
||||
var model = await _followUpDataService.GetByIdAsync(dto.Id);
|
||||
if (model == null) return NotFound();
|
||||
|
||||
model.Reason = dto.Reason;
|
||||
|
|
@ -219,19 +193,19 @@ public class FollowUpController : ControllerBase
|
|||
model.LocationId = dto.LocationId;
|
||||
model.LastModificationTime = DateTime.UtcNow;
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
await _followUpDataService.UpdateAsync(model);
|
||||
return Ok(new DataResponse { Status = "200", Message = "Follow Up updated" });
|
||||
}
|
||||
|
||||
[HttpPost("Complete")]
|
||||
public async Task<IActionResult> Complete(int id)
|
||||
{
|
||||
var model = await _db.FollowUps.FindAsync(id);
|
||||
var model = await _followUpDataService.GetByIdAsync(id);
|
||||
if (model == null) return NotFound();
|
||||
|
||||
model.Status = "Completed";
|
||||
model.LastModificationTime = DateTime.UtcNow;
|
||||
await _db.SaveChangesAsync();
|
||||
await _followUpDataService.UpdateAsync(model);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -239,12 +213,12 @@ public class FollowUpController : ControllerBase
|
|||
[HttpPost("Cancel")]
|
||||
public async Task<IActionResult> Cancel(int id)
|
||||
{
|
||||
var model = await _db.FollowUps.FindAsync(id);
|
||||
var model = await _followUpDataService.GetByIdAsync(id);
|
||||
if (model == null) return NotFound();
|
||||
|
||||
model.Status = "Cancelled";
|
||||
model.LastModificationTime = DateTime.UtcNow;
|
||||
await _db.SaveChangesAsync();
|
||||
await _followUpDataService.UpdateAsync(model);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -252,11 +226,10 @@ public class FollowUpController : ControllerBase
|
|||
[HttpPost("Delete")]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
var model = await _db.FollowUps.FindAsync(id);
|
||||
var model = await _followUpDataService.GetByIdAsync(id);
|
||||
if (model == null) return NotFound();
|
||||
|
||||
_db.FollowUps.Remove(model);
|
||||
await _db.SaveChangesAsync();
|
||||
await _followUpDataService.DeleteAsync(id);
|
||||
|
||||
return Ok(new DataResponse { Status = "200", Message = "Follow Up deleted" });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ using Data.SeaHavenIndustries;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
{
|
||||
|
|
@ -12,60 +15,44 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
[Route("api/locations")]
|
||||
public class LocationController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly ILocationService _locationService;
|
||||
private readonly ILocationDataService _locationDataService; // Keep for direct entity operations
|
||||
|
||||
public LocationController(ApplicationDbContext db)
|
||||
public LocationController(ILocationService locationService, ILocationDataService locationDataService)
|
||||
{
|
||||
_db = db;
|
||||
_locationService = locationService;
|
||||
_locationDataService = locationDataService;
|
||||
}
|
||||
|
||||
[HttpGet("GetLocationList")]
|
||||
public IActionResult GetLocationList(string? search = "", int page = 1, int pageSize = 10)
|
||||
public async Task<IActionResult> GetLocationList(string? search = "", int page = 1, int pageSize = 10)
|
||||
{
|
||||
var query = _db.Locations.AsQueryable();
|
||||
var pagedResult = await _locationService.GetLocationsPagedAsync(page, pageSize, search);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
var data = pagedResult.Items.Select(l => new
|
||||
{
|
||||
var s = search.ToLower();
|
||||
query = query.Where(l =>
|
||||
(l.Name ?? "").ToLower().Contains(s) ||
|
||||
(l.Title ?? "").ToLower().Contains(s) ||
|
||||
(l.Address1 ?? "").ToLower().Contains(s) ||
|
||||
(l.City ?? "").ToLower().Contains(s));
|
||||
}
|
||||
|
||||
var totalCount = query.Count();
|
||||
|
||||
var data = query
|
||||
.OrderByDescending(l => l.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(l => new
|
||||
{
|
||||
l.Id,
|
||||
l.Name,
|
||||
l.Title,
|
||||
Address = l.Address1, // Database has Address1, not Address
|
||||
l.Address1,
|
||||
l.Address2,
|
||||
l.City,
|
||||
l.State,
|
||||
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();
|
||||
Id = l.Id,
|
||||
Name = l.Name,
|
||||
Title = l.Title,
|
||||
Address = l.Address1,
|
||||
Address1 = l.Address1,
|
||||
Address2 = l.Address2,
|
||||
City = l.City,
|
||||
State = l.State,
|
||||
ZipCode = l.Zip,
|
||||
Phone = l.PhoneNumber,
|
||||
Contact = (string?)null,
|
||||
ContactEmail = l.Email,
|
||||
Status = l.Status
|
||||
});
|
||||
|
||||
var viewModel = new Pagination_DTO
|
||||
{
|
||||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize)
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize)
|
||||
};
|
||||
|
||||
return Ok(viewModel);
|
||||
|
|
@ -74,31 +61,29 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> GetLocationById(int id)
|
||||
{
|
||||
var location = await _db.Locations
|
||||
.Where(l => l.Id == id)
|
||||
.Select(l => new
|
||||
{
|
||||
l.Id,
|
||||
l.Name,
|
||||
l.Title,
|
||||
Address = l.Address1, // Database has Address1
|
||||
l.Address1,
|
||||
l.Address2,
|
||||
l.City,
|
||||
l.State,
|
||||
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();
|
||||
var location = await _locationDataService.GetByIdAsync(id);
|
||||
|
||||
if (location == null)
|
||||
return NotFound(new Response { Status = "Error", Message = "Location not found" });
|
||||
|
||||
return Ok(location);
|
||||
var result = new
|
||||
{
|
||||
location.Id,
|
||||
location.Name,
|
||||
location.Title,
|
||||
Address = location.Address1,
|
||||
location.Address1,
|
||||
location.Address2,
|
||||
location.City,
|
||||
location.State,
|
||||
ZipCode = location.Zip,
|
||||
Phone = location.PhoneNumber,
|
||||
Contact = (string?)null,
|
||||
ContactEmail = location.Email,
|
||||
location.Status
|
||||
};
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
|
@ -110,19 +95,17 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
Name = model.Name,
|
||||
Title = model.Title,
|
||||
Address1 = model.Address, // Map to Address1
|
||||
Address1 = model.Address,
|
||||
City = model.City,
|
||||
State = model.State,
|
||||
Zip = model.ZipCode, // Map to Zip
|
||||
PhoneNumber = model.Phone, // Map to PhoneNumber
|
||||
Email = model.ContactEmail, // Map to Email
|
||||
Zip = model.ZipCode,
|
||||
PhoneNumber = model.Phone,
|
||||
Email = model.ContactEmail,
|
||||
Status = model.Status,
|
||||
CreatedDate = DateTime.Now
|
||||
// Contact and AccountId don't exist in database
|
||||
};
|
||||
|
||||
_db.Locations.Add(location);
|
||||
await _db.SaveChangesAsync();
|
||||
await _locationDataService.AddAsync(location);
|
||||
return Ok(new DataResponse { Message = "Location Created Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -136,23 +119,22 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var exist = await _db.Locations.Where(l => l.Id == id).FirstOrDefaultAsync();
|
||||
var exist = await _locationDataService.GetByIdAsync(id);
|
||||
if (exist == null)
|
||||
return BadRequest(new Response { Status = "Error", Message = "Location not found" });
|
||||
|
||||
exist.Name = model.Name;
|
||||
exist.Title = model.Title;
|
||||
exist.Address1 = model.Address; // Map to Address1
|
||||
exist.Address1 = model.Address;
|
||||
exist.City = model.City;
|
||||
exist.State = model.State;
|
||||
exist.Zip = model.ZipCode; // Map to Zip
|
||||
exist.PhoneNumber = model.Phone; // Map to PhoneNumber
|
||||
exist.Email = model.ContactEmail; // Map to Email
|
||||
exist.Zip = model.ZipCode; // This is a property, not a method
|
||||
exist.PhoneNumber = model.Phone;
|
||||
exist.Email = model.ContactEmail;
|
||||
exist.Status = model.Status;
|
||||
exist.LastModificationTime = DateTime.Now;
|
||||
// Contact and AccountId don't exist in database
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
await _locationDataService.UpdateAsync(exist);
|
||||
return Ok(new DataResponse { Message = "Location Updated Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -166,12 +148,11 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var exist = await _db.Locations.Where(l => l.Id == id).FirstOrDefaultAsync();
|
||||
var exist = await _locationDataService.GetByIdAsync(id);
|
||||
if (exist == null)
|
||||
return BadRequest(new Response { Status = "Error", Message = "Location not found" });
|
||||
|
||||
_db.Locations.Remove(exist);
|
||||
await _db.SaveChangesAsync();
|
||||
await _locationDataService.DeleteAsync(id);
|
||||
return Ok(new DataResponse { Message = "Location Deleted Successfully", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -2,37 +2,36 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/PMSchedule")]
|
||||
[Route("api/pmschedules")]
|
||||
public class PMScheduleController : ControllerBase
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IPMScheduleService _pmScheduleService;
|
||||
|
||||
public PMScheduleController(ApplicationDbContext db)
|
||||
public PMScheduleController(IPMScheduleService pmScheduleService)
|
||||
{
|
||||
_db = db;
|
||||
_pmScheduleService = pmScheduleService;
|
||||
}
|
||||
|
||||
[HttpGet("GetList")]
|
||||
public IActionResult GetList()
|
||||
public async Task<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();
|
||||
var items = await _pmScheduleService.GetAllPMSchedulesAsync();
|
||||
|
||||
var data = items.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Frequency = x.Frequency,
|
||||
StartDate = x.StartDate,
|
||||
IsActive = x.IsActive,
|
||||
Asset = x.AssetName,
|
||||
Location = x.LocationName
|
||||
});
|
||||
|
||||
return Ok(data);
|
||||
}
|
||||
|
|
@ -40,31 +39,42 @@ public class PMScheduleController : ControllerBase
|
|||
[HttpPost("Save")]
|
||||
public async Task<IActionResult> Save(PMSchedule_DTO dto)
|
||||
{
|
||||
PMSchedules model;
|
||||
|
||||
if (dto.Id == 0)
|
||||
try
|
||||
{
|
||||
model = new PMSchedules
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
|
||||
if (dto.Id == 0)
|
||||
{
|
||||
CreatedDate = DateTime.UtcNow
|
||||
};
|
||||
_db.PMSchedules.Add(model);
|
||||
var createDto = new CreatePMScheduleDTO
|
||||
{
|
||||
Name = dto.Name,
|
||||
Frequency = dto.Frequency,
|
||||
StartDate = dto.StartDate,
|
||||
IsActive = dto.IsActive,
|
||||
AssetId = dto.AssetId,
|
||||
LocationId = dto.LocationId
|
||||
};
|
||||
await _pmScheduleService.CreatePMScheduleAsync(createDto, userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var updateDto = new UpdatePMScheduleDTO
|
||||
{
|
||||
Name = dto.Name,
|
||||
Frequency = dto.Frequency,
|
||||
StartDate = dto.StartDate,
|
||||
IsActive = dto.IsActive,
|
||||
AssetId = dto.AssetId,
|
||||
LocationId = dto.LocationId
|
||||
};
|
||||
await _pmScheduleService.UpdatePMScheduleAsync(dto.Id, updateDto, userId);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
model = await _db.PMSchedules.FindAsync(dto.Id);
|
||||
if (model == null) return NotFound();
|
||||
model.LastModificationTime = DateTime.UtcNow;
|
||||
return BadRequest(new { Message = ex.Message });
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ using Data.SeaHavenIndustries;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
{
|
||||
|
|
@ -12,13 +14,15 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
[Route("api/vendors")]
|
||||
public class VendorController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IVendorService _vendorService;
|
||||
private readonly ApplicationDbContext _db; // Keep for complex queries like nearby vendors
|
||||
private readonly Helper.ZipCodeDistance _zipDistance;
|
||||
private readonly Helper.VendorPortalTokenService _vendorTokens;
|
||||
private readonly IConfiguration _config;
|
||||
|
||||
public VendorController(ApplicationDbContext db, Helper.ZipCodeDistance zipDistance, Helper.VendorPortalTokenService vendorTokens, IConfiguration config)
|
||||
public VendorController(IVendorService vendorService, ApplicationDbContext db, Helper.ZipCodeDistance zipDistance, Helper.VendorPortalTokenService vendorTokens, IConfiguration config)
|
||||
{
|
||||
_vendorService = vendorService;
|
||||
_db = db;
|
||||
_zipDistance = zipDistance;
|
||||
_vendorTokens = vendorTokens;
|
||||
|
|
@ -26,64 +30,32 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
|
||||
[HttpGet("GetVendorList")]
|
||||
public IActionResult GetVendorList(string? search = "", int page = 1, int pageSize = 10)
|
||||
public async Task<IActionResult> GetVendorList(string? search = "", int page = 1, int pageSize = 10)
|
||||
{
|
||||
var query = _db.Vendors.Where(v => v.IsActive);
|
||||
var pagedResult = await _vendorService.GetVendorsPagedAsync(page, pageSize, search);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
var data = pagedResult.Items.Select(v => new
|
||||
{
|
||||
var s = search.ToLower();
|
||||
query = query.Where(v =>
|
||||
(v.CompanyName ?? "").ToLower().Contains(s) ||
|
||||
(v.ContactName ?? "").ToLower().Contains(s) ||
|
||||
(v.Email ?? "").ToLower().Contains(s) ||
|
||||
(v.TradeSpecialties ?? "").ToLower().Contains(s));
|
||||
}
|
||||
|
||||
var totalCount = query.Count();
|
||||
|
||||
var data = query.OrderByDescending(v => v.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(v => new
|
||||
{
|
||||
v.Id,
|
||||
v.CompanyName,
|
||||
v.ContactName,
|
||||
v.Email,
|
||||
v.Phone,
|
||||
v.TradeSpecialties,
|
||||
v.IsActive
|
||||
})
|
||||
.ToList();
|
||||
v.Id,
|
||||
CompanyName = v.Name,
|
||||
v.Email,
|
||||
v.Phone
|
||||
});
|
||||
|
||||
return Ok(new Pagination_DTO
|
||||
{
|
||||
Data = data,
|
||||
PageNumber = page,
|
||||
PageSize = pageSize,
|
||||
TotalCount = totalCount,
|
||||
TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize)
|
||||
TotalCount = pagedResult.TotalCount,
|
||||
TotalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize)
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> GetVendorById(int id)
|
||||
{
|
||||
var vendor = await _db.Vendors.Where(v => v.Id == id).Select(v => new
|
||||
{
|
||||
v.Id,
|
||||
v.CompanyName,
|
||||
v.ContactName,
|
||||
v.Email,
|
||||
v.Phone,
|
||||
v.Address,
|
||||
v.City,
|
||||
v.State,
|
||||
v.Zip,
|
||||
v.TradeSpecialties,
|
||||
v.IsActive
|
||||
}).FirstOrDefaultAsync();
|
||||
var vendor = await _vendorService.GetVendorByIdAsync(id);
|
||||
|
||||
if (vendor == null)
|
||||
return NotFound(new Response { Status = "Error", Message = "Vendor not found" });
|
||||
|
|
@ -96,21 +68,13 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var vendor = new Vendor
|
||||
var createDto = new CreateVendorDTO
|
||||
{
|
||||
CompanyName = model.CompanyName,
|
||||
ContactName = model.ContactName,
|
||||
Email = model.Email,
|
||||
Phone = model.Phone,
|
||||
Address = model.Address,
|
||||
City = model.City,
|
||||
State = model.State,
|
||||
Zip = model.Zip,
|
||||
TradeSpecialties = model.TradeSpecialties,
|
||||
IsActive = model.IsActive
|
||||
Name = model.CompanyName ?? throw new ArgumentException("CompanyName is required")
|
||||
};
|
||||
_db.Vendors.Add(vendor);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _vendorService.CreateVendorAsync(createDto, userId);
|
||||
return Ok(new DataResponse { Message = "Vendor Created", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -124,22 +88,13 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
var exist = await _db.Vendors.FindAsync(id);
|
||||
if (exist == null)
|
||||
return BadRequest(new Response { Status = "Error", Message = "Vendor not found" });
|
||||
var updateDto = new UpdateVendorDTO
|
||||
{
|
||||
Name = model.CompanyName
|
||||
};
|
||||
|
||||
exist.CompanyName = model.CompanyName;
|
||||
exist.ContactName = model.ContactName;
|
||||
exist.Email = model.Email;
|
||||
exist.Phone = model.Phone;
|
||||
exist.Address = model.Address;
|
||||
exist.City = model.City;
|
||||
exist.State = model.State;
|
||||
exist.Zip = model.Zip;
|
||||
exist.TradeSpecialties = model.TradeSpecialties;
|
||||
exist.IsActive = model.IsActive;
|
||||
|
||||
await _db.SaveChangesAsync();
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _vendorService.UpdateVendorAsync(id, updateDto, userId);
|
||||
return Ok(new DataResponse { Message = "Vendor Updated", Status = "200" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -151,12 +106,8 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
var exist = await _db.Vendors.FindAsync(id);
|
||||
if (exist == null)
|
||||
return BadRequest(new Response { Status = "Error", Message = "Vendor not found" });
|
||||
|
||||
_db.Vendors.Remove(exist);
|
||||
await _db.SaveChangesAsync();
|
||||
var userId = User.Identity?.Name ?? "system";
|
||||
await _vendorService.DeleteVendorAsync(id, userId);
|
||||
return Ok(new DataResponse { Message = "Vendor Deleted", Status = "200" });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using System.IO;
|
|||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
|
||||
namespace Api.SeaHavenIndustries.Controllers
|
||||
{
|
||||
|
|
@ -23,15 +24,26 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
public class WorkOrderController : Controller
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IWorkOrderDataService _workOrderDataService;
|
||||
private readonly ApplicationDbContext _db; // Keep for complex operations, file handling, dispatch, comments
|
||||
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||
IHttpContextAccessor _httpContext;
|
||||
private readonly Helper.SendMessage _sendMessage;
|
||||
private readonly Helper.VendorPortalTokenService _vendorTokens;
|
||||
private readonly IConfiguration _config;
|
||||
public WorkOrderController(UserManager<ApplicationUser> userManager, ApplicationDbContext db, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContext, Helper.SendMessage sendMessage, Helper.VendorPortalTokenService vendorTokens, IConfiguration config)
|
||||
|
||||
public WorkOrderController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
IWorkOrderDataService workOrderDataService,
|
||||
ApplicationDbContext db,
|
||||
IWebHostEnvironment webHostEnvironment,
|
||||
IHttpContextAccessor httpContext,
|
||||
Helper.SendMessage sendMessage,
|
||||
Helper.VendorPortalTokenService vendorTokens,
|
||||
IConfiguration config)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_workOrderDataService = workOrderDataService;
|
||||
_db = db;
|
||||
_webHostEnvironment = webHostEnvironment;
|
||||
_httpContext = httpContext;
|
||||
|
|
@ -373,79 +385,17 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
// GET: api/WorkOrder/GetWorkOrderList
|
||||
// -----------------------------------
|
||||
[HttpGet("GetWorkOrderList")]
|
||||
public IActionResult GetWorkOrderList(string? search = "", int page = 1, int pageSize = 12, string? sortBy = "lastUpdated", string? sortDir = "desc", string? status = "", string? assignee = "", int? locationId = null)
|
||||
public async Task<IActionResult> GetWorkOrderList(string? search = "", int page = 1, int pageSize = 12, string? sortBy = "lastUpdated", string? sortDir = "desc", string? status = "", string? assignee = "", int? locationId = null)
|
||||
{
|
||||
search ??= "";
|
||||
|
||||
var query = _db.workOrders
|
||||
.Include(w => w.Locations)
|
||||
.Include(w => w.AssignToUser)
|
||||
.Where(w => w.istemplate != true);
|
||||
|
||||
if (locationId.HasValue)
|
||||
query = query.Where(w => w.LocationId == locationId.Value);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
query = query.Where(w => w.Status == status);
|
||||
|
||||
if (assignee == "__unassigned")
|
||||
query = query.Where(w => w.AssignTo == null || w.AssignTo == "");
|
||||
else if (!string.IsNullOrWhiteSpace(assignee))
|
||||
query = query.Where(w => w.AssignToUser != null && (w.AssignToUser.FirstName + " " + w.AssignToUser.LastName).Contains(assignee));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
var s = search.ToLower();
|
||||
query = query.Where(w =>
|
||||
(w.InternalWONumber ?? "").ToLower().Contains(s) ||
|
||||
(w.WorkerOrderNumber ?? "").ToLower().Contains(s) ||
|
||||
(w.WorkerOrderTitle ?? "").ToLower().Contains(s) ||
|
||||
(w.Locations.Title ?? "").ToLower().Contains(s) ||
|
||||
(w.Locations.Name ?? "").ToLower().Contains(s)
|
||||
);
|
||||
}
|
||||
|
||||
var totalCount = query.Count();
|
||||
|
||||
var isAsc = sortDir?.ToLower() == "asc";
|
||||
IOrderedQueryable<WorkOrder> ordered = (sortBy?.ToLower()) switch
|
||||
{
|
||||
"number" => isAsc ? query.OrderBy(w => w.InternalWONumber) : query.OrderByDescending(w => w.InternalWONumber),
|
||||
"title" => isAsc ? query.OrderBy(w => w.WorkerOrderTitle) : query.OrderByDescending(w => w.WorkerOrderTitle),
|
||||
"location" => isAsc ? query.OrderBy(w => w.Locations != null ? w.Locations.Name : "") : query.OrderByDescending(w => w.Locations != null ? w.Locations.Name : ""),
|
||||
"priority" => isAsc ? query.OrderBy(w => w.Priority) : query.OrderByDescending(w => w.Priority),
|
||||
"status" => isAsc ? query.OrderBy(w => w.Status) : query.OrderByDescending(w => w.Status),
|
||||
"createddate" => isAsc ? query.OrderBy(w => w.CreatedDate) : query.OrderByDescending(w => w.CreatedDate),
|
||||
"assignedto" => isAsc ? query.OrderBy(w => w.AssignToUser != null ? w.AssignToUser.FirstName : "") : query.OrderByDescending(w => w.AssignToUser != null ? w.AssignToUser.FirstName : ""),
|
||||
"lastupdated" => isAsc ? query.OrderBy(w => w.LastModificationTime) : query.OrderByDescending(w => w.LastModificationTime),
|
||||
_ => query.OrderByDescending(w => w.Id)
|
||||
};
|
||||
|
||||
var data = ordered
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(w => new
|
||||
{
|
||||
id = w.Id,
|
||||
internalWONumber = w.InternalWONumber,
|
||||
workOrderNumber = w.WorkerOrderNumber,
|
||||
number = w.InternalWONumber ?? w.WorkerOrderNumber,
|
||||
title = w.WorkerOrderTitle,
|
||||
location = w.Locations != null ? w.Locations.Name : "",
|
||||
locationName = w.Locations != null ? w.Locations.Name : "",
|
||||
priority = w.Priority,
|
||||
status = w.Status,
|
||||
createdDate = w.CreatedDate,
|
||||
dueDate = w.DueDate,
|
||||
assignedTo = w.AssignToUser != null ? w.AssignToUser.FirstName + " " + w.AssignToUser.LastName : "",
|
||||
employeeName = w.AssignToUser != null ? w.AssignToUser.FirstName + " " + w.AssignToUser.LastName : "",
|
||||
lastUpdated = new[] {
|
||||
w.LastModificationTime,
|
||||
w.Comments.Max(c => (DateTime?)c.CreatedDate),
|
||||
_db.WorkOrderAuditLogs.Where(a => a.WorkOrderId == w.Id).Max(a => (DateTime?)a.CreatedAt)
|
||||
}.Where(d => d.HasValue).Max()
|
||||
})
|
||||
.ToList();
|
||||
var (data, totalCount) = await _workOrderDataService.GetWorkOrderListPagedAsync(
|
||||
page,
|
||||
pageSize,
|
||||
search,
|
||||
status,
|
||||
assignee,
|
||||
locationId,
|
||||
sortBy,
|
||||
sortDir);
|
||||
|
||||
var viewModel = new Pagination_DTO
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
namespace Api.SeaHavenIndustries.DTOs
|
||||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
namespace Api.SeaHavenIndustries.DTOs
|
||||
{
|
||||
public class Contact_DTO
|
||||
{
|
||||
|
|
@ -20,5 +23,100 @@
|
|||
public string? TwitterUrl { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
public int? AccountId { get; set; }
|
||||
|
||||
// ✅ Map API DTO to Service DTO
|
||||
public CreateContactDTO ToServiceCreateDTO()
|
||||
{
|
||||
return new CreateContactDTO
|
||||
{
|
||||
FirstName = this.FirstName,
|
||||
LastName = this.LastName,
|
||||
Email = this.Email ?? "",
|
||||
Phone = this.PhoneNumber,
|
||||
Title = this.Title,
|
||||
Type = this.ContactType,
|
||||
AccountId = this.AccountId
|
||||
};
|
||||
}
|
||||
|
||||
// Map from Entity to DTO (Model)
|
||||
public static Contact_DTO MapToModel(Contacts entity)
|
||||
{
|
||||
return new Contact_DTO
|
||||
{
|
||||
Title = entity.Title,
|
||||
Owner = entity.Owner,
|
||||
FirstName = entity.FirstName,
|
||||
MiddleName = entity.MiddleName,
|
||||
LastName = entity.LastName,
|
||||
ContactType = entity.ContactType,
|
||||
PhoneNumber = entity.PhoneNumber,
|
||||
Email = entity.Email,
|
||||
Address1 = entity.Address1,
|
||||
Address2 = entity.Address2,
|
||||
City = entity.City,
|
||||
State = entity.State,
|
||||
Zip = entity.Zip,
|
||||
FacebookUrl = entity.FacebookUrl,
|
||||
LinkedInUrl = entity.LinkedInUrl,
|
||||
TwitterUrl = entity.TwitterUrl,
|
||||
LocationId = entity.LocationId,
|
||||
AccountId = entity.AccountId
|
||||
};
|
||||
}
|
||||
|
||||
// Map from DTO (Model) to Entity
|
||||
public static Contacts MapToEntity(Contact_DTO dto, Contacts? existingEntity = null)
|
||||
{
|
||||
var entity = existingEntity ?? new Contacts();
|
||||
|
||||
entity.Title = dto.Title;
|
||||
entity.Owner = dto.Owner;
|
||||
entity.FirstName = dto.FirstName;
|
||||
entity.MiddleName = dto.MiddleName;
|
||||
entity.LastName = dto.LastName;
|
||||
entity.ContactType = dto.ContactType;
|
||||
entity.PhoneNumber = dto.PhoneNumber;
|
||||
entity.Email = dto.Email;
|
||||
entity.Address1 = dto.Address1;
|
||||
entity.Address2 = dto.Address2;
|
||||
entity.City = dto.City;
|
||||
entity.State = dto.State;
|
||||
entity.Zip = dto.Zip;
|
||||
entity.FacebookUrl = dto.FacebookUrl;
|
||||
entity.LinkedInUrl = dto.LinkedInUrl;
|
||||
entity.TwitterUrl = dto.TwitterUrl;
|
||||
entity.LocationId = dto.LocationId;
|
||||
entity.AccountId = dto.AccountId;
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
// DTO for contact list view
|
||||
public class ContactListItem_DTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
|
||||
// ✅ Map from Service DTO
|
||||
public static ContactListItem_DTO FromServiceDTO(ContactDTO serviceDto)
|
||||
{
|
||||
return new ContactListItem_DTO
|
||||
{
|
||||
Id = serviceDto.Id,
|
||||
Name = (serviceDto.FirstName + " " + serviceDto.LastName).Trim(),
|
||||
Email = serviceDto.Email,
|
||||
Phone = serviceDto.Phone
|
||||
};
|
||||
}
|
||||
|
||||
// ✅ Map collection from Service DTOs
|
||||
public static IEnumerable<ContactListItem_DTO> FromServiceDTOs(IEnumerable<ContactDTO> serviceDtos)
|
||||
{
|
||||
return serviceDtos.Select(FromServiceDTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
namespace Api.SeaHavenIndustries.DTOs
|
||||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
namespace Api.SeaHavenIndustries.DTOs
|
||||
{
|
||||
public class EditContact_DTO
|
||||
{
|
||||
|
|
@ -21,5 +24,72 @@
|
|||
public string? TwitterUrl { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
public int? AccountId { get; set; }
|
||||
|
||||
// ✅ Map API DTO to Service DTO
|
||||
public UpdateContactDTO ToServiceUpdateDTO()
|
||||
{
|
||||
return new UpdateContactDTO
|
||||
{
|
||||
FirstName = this.FirstName,
|
||||
LastName = this.LastName,
|
||||
Email = this.Email,
|
||||
Phone = this.PhoneNumber,
|
||||
Title = this.Title,
|
||||
Type = this.ContactType,
|
||||
AccountId = this.AccountId
|
||||
};
|
||||
}
|
||||
|
||||
// Map from Entity to DTO (Model)
|
||||
public static EditContact_DTO MapToModel(Contacts entity)
|
||||
{
|
||||
return new EditContact_DTO
|
||||
{
|
||||
Id = entity.Id,
|
||||
Title = entity.Title,
|
||||
Owner = entity.Owner,
|
||||
FirstName = entity.FirstName,
|
||||
MiddleName = entity.MiddleName,
|
||||
LastName = entity.LastName,
|
||||
ContactType = entity.ContactType,
|
||||
PhoneNumber = entity.PhoneNumber,
|
||||
Email = entity.Email,
|
||||
Address1 = entity.Address1,
|
||||
Address2 = entity.Address2,
|
||||
City = entity.City,
|
||||
State = entity.State,
|
||||
Zip = entity.Zip,
|
||||
FacebookUrl = entity.FacebookUrl,
|
||||
LinkedInUrl = entity.LinkedInUrl,
|
||||
TwitterUrl = entity.TwitterUrl,
|
||||
LocationId = entity.LocationId,
|
||||
AccountId = entity.AccountId
|
||||
};
|
||||
}
|
||||
|
||||
// Map from DTO (Model) to Entity - updates existing entity
|
||||
public static Contacts MapToEntity(EditContact_DTO dto, Contacts existingEntity)
|
||||
{
|
||||
existingEntity.Title = dto.Title;
|
||||
existingEntity.Owner = dto.Owner;
|
||||
existingEntity.FirstName = dto.FirstName;
|
||||
existingEntity.MiddleName = dto.MiddleName;
|
||||
existingEntity.LastName = dto.LastName;
|
||||
existingEntity.ContactType = dto.ContactType;
|
||||
existingEntity.PhoneNumber = dto.PhoneNumber;
|
||||
existingEntity.Email = dto.Email;
|
||||
existingEntity.Address1 = dto.Address1;
|
||||
existingEntity.Address2 = dto.Address2;
|
||||
existingEntity.City = dto.City;
|
||||
existingEntity.State = dto.State;
|
||||
existingEntity.Zip = dto.Zip;
|
||||
existingEntity.FacebookUrl = dto.FacebookUrl;
|
||||
existingEntity.LinkedInUrl = dto.LinkedInUrl;
|
||||
existingEntity.TwitterUrl = dto.TwitterUrl;
|
||||
existingEntity.LocationId = dto.LocationId;
|
||||
existingEntity.AccountId = dto.AccountId;
|
||||
|
||||
return existingEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using SeaHaven.Services.DTOs;
|
||||
|
||||
namespace Api.SeaHavenIndustries.DTOs
|
||||
{
|
||||
public class EditLocation_DTO
|
||||
|
|
@ -17,5 +19,19 @@ namespace Api.SeaHavenIndustries.DTOs
|
|||
|
||||
public int? GetAccountId() =>
|
||||
int.TryParse(AccountId, out var id) ? id : null;
|
||||
|
||||
// ✅ Map API DTO to Service DTO
|
||||
public UpdateLocationDTO ToServiceUpdateDTO()
|
||||
{
|
||||
return new UpdateLocationDTO
|
||||
{
|
||||
LocationName = this.Name,
|
||||
Address = this.Address,
|
||||
City = this.City,
|
||||
State = this.State,
|
||||
Zipcode = this.ZipCode,
|
||||
AccountId = this.GetAccountId()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.Services.DTOs;
|
||||
|
||||
namespace Api.SeaHavenIndustries.DTOs
|
||||
{
|
||||
public class Location_DTO
|
||||
|
|
@ -16,5 +19,117 @@ namespace Api.SeaHavenIndustries.DTOs
|
|||
|
||||
public int? GetAccountId() =>
|
||||
int.TryParse(AccountId, out var id) ? id : null;
|
||||
|
||||
// ✅ Map API DTO to Service DTO
|
||||
public CreateLocationDTO ToServiceCreateDTO()
|
||||
{
|
||||
return new CreateLocationDTO
|
||||
{
|
||||
LocationName = this.Name ?? "",
|
||||
Address = this.Address,
|
||||
City = this.City,
|
||||
State = this.State,
|
||||
Zipcode = this.ZipCode,
|
||||
AccountId = this.GetAccountId()
|
||||
};
|
||||
}
|
||||
|
||||
// Map from Entity to DTO
|
||||
public static Location_DTO MapToModel(Locations entity)
|
||||
{
|
||||
return new Location_DTO
|
||||
{
|
||||
Title = entity.Title,
|
||||
Name = entity.Name,
|
||||
Address = entity.Address1,
|
||||
City = entity.City,
|
||||
State = entity.State,
|
||||
ZipCode = entity.Zip,
|
||||
Phone = entity.PhoneNumber,
|
||||
Contact = null, // Not in database schema
|
||||
ContactEmail = entity.Email,
|
||||
Status = entity.Status,
|
||||
AccountId = null // Not in database schema
|
||||
};
|
||||
}
|
||||
|
||||
// Map from DTO to Entity
|
||||
public static Locations MapToEntity(Location_DTO dto, Locations? existingEntity = null)
|
||||
{
|
||||
var entity = existingEntity ?? new Locations();
|
||||
|
||||
entity.Title = dto.Title;
|
||||
entity.Name = dto.Name;
|
||||
entity.Address1 = dto.Address;
|
||||
entity.City = dto.City;
|
||||
entity.State = dto.State;
|
||||
entity.Zip = dto.ZipCode;
|
||||
entity.PhoneNumber = dto.Phone;
|
||||
// Contact field doesn't exist in database schema - ignored
|
||||
entity.Email = dto.ContactEmail;
|
||||
entity.Status = dto.Status;
|
||||
// AccountId field doesn't exist in database schema - ignored
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
// DTO for list views
|
||||
public class LocationListItem_DTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Title { get; set; }
|
||||
|
||||
// Map from Entity
|
||||
public static LocationListItem_DTO MapToModel(Locations entity)
|
||||
{
|
||||
return new LocationListItem_DTO
|
||||
{
|
||||
Id = entity.Id,
|
||||
Name = entity.Name,
|
||||
Title = entity.Title
|
||||
};
|
||||
}
|
||||
|
||||
// ✅ Map from Service DTO (no logic in controller)
|
||||
public static LocationListItem_DTO FromServiceDTO(LocationDTO serviceDto)
|
||||
{
|
||||
return new LocationListItem_DTO
|
||||
{
|
||||
Id = serviceDto.Id,
|
||||
Name = serviceDto.Name ?? serviceDto.Title,
|
||||
Title = serviceDto.Title ?? serviceDto.Name
|
||||
};
|
||||
}
|
||||
|
||||
// ✅ Map collection from Service DTOs
|
||||
public static IEnumerable<LocationListItem_DTO> FromServiceDTOs(IEnumerable<LocationDTO> serviceDtos)
|
||||
{
|
||||
return serviceDtos.Select(FromServiceDTO);
|
||||
}
|
||||
}
|
||||
|
||||
// DTO for location dropdown/simple view
|
||||
public class LocationViewModel_DTO
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
|
||||
// ✅ Map from Service DTO
|
||||
public static LocationViewModel_DTO FromServiceDTO(LocationDTO serviceDto)
|
||||
{
|
||||
return new LocationViewModel_DTO
|
||||
{
|
||||
Id = serviceDto.Id,
|
||||
Name = serviceDto.Name ?? serviceDto.Title
|
||||
};
|
||||
}
|
||||
|
||||
// ✅ Map collection from Service DTOs
|
||||
public static IEnumerable<LocationViewModel_DTO> FromServiceDTOs(IEnumerable<LocationDTO> serviceDtos)
|
||||
{
|
||||
return serviceDtos.Select(FromServiceDTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,12 +60,17 @@ builder.Services.AddScoped<SeaHaven.DataServices.Interfaces.IPMScheduleDataServi
|
|||
builder.Services.AddScoped<SeaHaven.DataServices.Interfaces.IAssetDataService, SeaHaven.DataServices.Implementation.AssetDataService>();
|
||||
builder.Services.AddScoped<SeaHaven.DataServices.Interfaces.ICategoryDataService, SeaHaven.DataServices.Implementation.CategoryDataService>();
|
||||
|
||||
// Business Services (Business Logic Layer) - Only register services that exist
|
||||
// Business Services (Business Logic Layer)
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IContactService, SeaHaven.Services.Implementation.ContactService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IWorkOrderService, SeaHaven.Services.Implementation.WorkOrderService>();
|
||||
// TODO: Add other business services as they are implemented
|
||||
// - LocationService, EmployeeService, AccountService, VendorService, DispatchService
|
||||
// - FollowUpService, PMScheduleService, AssetService, CategoryService
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.ILocationService, SeaHaven.Services.Implementation.LocationService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IEmployeeService, SeaHaven.Services.Implementation.EmployeeService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IAccountService, SeaHaven.Services.Implementation.AccountService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IVendorService, SeaHaven.Services.Implementation.VendorService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IDispatchService, SeaHaven.Services.Implementation.DispatchService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IFollowUpService, SeaHaven.Services.Implementation.FollowUpService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IPMScheduleService, SeaHaven.Services.Implementation.PMScheduleService>();
|
||||
builder.Services.AddScoped<SeaHaven.Services.Interfaces.IAssetService, SeaHaven.Services.Implementation.AssetService>();
|
||||
|
||||
// ========================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -86,8 +86,9 @@ namespace Data.SeaHavenIndustries
|
|||
public Employee Employee { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class EmployeeEmail : FullAuditEntity
|
||||
public class EmployeeEmail
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int EmployeeId { get; set; }
|
||||
public Employee? Employee { get; set; }
|
||||
|
||||
|
|
@ -99,22 +100,28 @@ namespace Data.SeaHavenIndustries
|
|||
public bool? IsPrimary { get; set; }
|
||||
}
|
||||
|
||||
public class Department : FullAuditEntity
|
||||
public class Department
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[MaxLength(200)]
|
||||
public string Name { get; set; } = null!;
|
||||
public ICollection<Employee>? Employees { get; set; }
|
||||
}
|
||||
|
||||
public class JobTitle : FullAuditEntity
|
||||
public class JobTitle
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[MaxLength(200)]
|
||||
public string Name { get; set; } = null!;
|
||||
public ICollection<Employee>? Employees { get; set; }
|
||||
}
|
||||
|
||||
public class Region : FullAuditEntity
|
||||
public class Region
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[MaxLength(200)]
|
||||
public string Name { get; set; } = null!;
|
||||
public ICollection<Employee>? Employees { get; set; }
|
||||
|
|
|
|||
|
|
@ -32,20 +32,29 @@ namespace SeaHaven.DataServices.Implementation
|
|||
}
|
||||
|
||||
public async Task<(IEnumerable<Accounts> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null)
|
||||
{
|
||||
var query = _context.Accounts.AsQueryable();
|
||||
search ??= "";
|
||||
|
||||
var query = _context.Accounts
|
||||
.Where(a => a.IsDeleted == false || a.IsDeleted == null);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
query = query.Where(a => a.Name!.Contains(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 = await query.CountAsync();
|
||||
var items = await query
|
||||
.OrderBy(a => a.Name)
|
||||
.OrderByDescending(a => a.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ namespace SeaHaven.DataServices.Implementation
|
|||
public async Task<Assets?> GetByIdWithDetailsAsync(int id)
|
||||
{
|
||||
return await _context.Assets
|
||||
.Include(a => a.Account)
|
||||
.Include(a => a.Location)
|
||||
.FirstOrDefaultAsync(a => a.Id == id);
|
||||
}
|
||||
|
||||
|
|
@ -37,15 +39,30 @@ namespace SeaHaven.DataServices.Implementation
|
|||
}
|
||||
|
||||
public async Task<(IEnumerable<Assets> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null)
|
||||
{
|
||||
var query = _context.Assets.AsQueryable();
|
||||
search ??= "";
|
||||
|
||||
var query = _context.Assets
|
||||
.Include(a => a.Account)
|
||||
.Include(a => a.Location)
|
||||
.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
var s = search.ToLower();
|
||||
query = query.Where(a =>
|
||||
(a.Name != null && a.Name.ToLower().Contains(s)) ||
|
||||
(a.AssetCode != null && a.AssetCode.ToLower().Contains(s)) ||
|
||||
(a.Description != null && a.Description.ToLower().Contains(s))
|
||||
);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
var items = await query
|
||||
.OrderBy(a => a.Id)
|
||||
.OrderByDescending(a => a.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
|
|
|||
|
|
@ -65,18 +65,22 @@ namespace SeaHaven.DataServices.Implementation
|
|||
}
|
||||
|
||||
public async Task<(IEnumerable<Contacts> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
string? type = null)
|
||||
{
|
||||
search ??= "";
|
||||
var query = _context.Contacts.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
query = query.Where(c =>
|
||||
(c.FirstName + " " + c.LastName).Contains(search) ||
|
||||
c.Email!.Contains(search));
|
||||
var s = search.ToLower();
|
||||
query = query.Where(c =>
|
||||
(c.FirstName != null && c.FirstName.ToLower().Contains(s)) ||
|
||||
(c.LastName != null && c.LastName.ToLower().Contains(s)) ||
|
||||
(c.Email != null && c.Email.ToLower().Contains(s)) ||
|
||||
(c.PhoneNumber != null && c.PhoneNumber.Contains(s)));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(type))
|
||||
|
|
@ -86,7 +90,7 @@ namespace SeaHaven.DataServices.Implementation
|
|||
|
||||
var totalCount = await query.CountAsync();
|
||||
var items = await query
|
||||
.OrderBy(c => c.LastName)
|
||||
.OrderByDescending(c => c.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ namespace SeaHaven.DataServices.Implementation
|
|||
return await _context.Employees
|
||||
.Include(e => e.Department)
|
||||
.Include(e => e.JobTitle)
|
||||
.Include(e => e.Region)
|
||||
.Include(e => e.Emails)
|
||||
.Include(e => e.Phones)
|
||||
.FirstOrDefaultAsync(e => e.Id == id);
|
||||
}
|
||||
|
||||
|
|
@ -33,20 +35,34 @@ namespace SeaHaven.DataServices.Implementation
|
|||
}
|
||||
|
||||
public async Task<(IEnumerable<Employee> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null)
|
||||
{
|
||||
var query = _context.Employees.AsQueryable();
|
||||
search ??= "";
|
||||
|
||||
var query = _context.Employees
|
||||
.Include(e => e.JobTitle)
|
||||
.Include(e => e.Department)
|
||||
.Include(e => e.Region)
|
||||
.Include(e => e.Emails)
|
||||
.Include(e => e.Phones)
|
||||
.Where(e => !e.IsDeleted.HasValue || e.IsDeleted == false);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
query = query.Where(e => (e.FirstName + " " + e.LastName).Contains(search));
|
||||
var s = search.ToLower();
|
||||
query = query.Where(e =>
|
||||
(e.FirstName != null && e.FirstName.ToLower().Contains(s)) ||
|
||||
(e.LastName != null && e.LastName.ToLower().Contains(s)) ||
|
||||
e.Emails.Any(x => x.Address != null && x.Address.ToLower().Contains(s)) ||
|
||||
e.Phones.Any(x => x.Number != null && x.Number.Contains(search))
|
||||
);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
var items = await query
|
||||
.OrderBy(e => e.LastName)
|
||||
.OrderByDescending(e => e.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ namespace SeaHaven.DataServices.Implementation
|
|||
public async Task<FollowUps?> GetByIdWithDetailsAsync(int id)
|
||||
{
|
||||
return await _context.FollowUps
|
||||
.Include(x => x.Employee)
|
||||
.Include(x => x.Account)
|
||||
.Include(x => x.Location)
|
||||
// Removed .Include(x => x.WorkOrder) due to schema mismatch - WorkOrder has columns not in DB
|
||||
.FirstOrDefaultAsync(f => f.Id == id);
|
||||
}
|
||||
|
||||
|
|
@ -44,21 +48,37 @@ namespace SeaHaven.DataServices.Implementation
|
|||
}
|
||||
|
||||
public async Task<(IEnumerable<FollowUps> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
string? status = null)
|
||||
{
|
||||
var query = _context.FollowUps.AsQueryable();
|
||||
search ??= "";
|
||||
status = string.IsNullOrWhiteSpace(status) ? "Open" : status;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
var query = _context.FollowUps
|
||||
.Include(x => x.Employee)
|
||||
.Include(x => x.Account)
|
||||
.Include(x => x.Location)
|
||||
// Removed .Include(x => x.WorkOrder) due to schema mismatch - WorkOrder has columns not in DB
|
||||
.Where(x => x.Status == status);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
query = query.Where(f => f.Status == status);
|
||||
var s = search.ToLower();
|
||||
query = query.Where(x =>
|
||||
(x.Reason ?? "").ToLower().Contains(s) ||
|
||||
(x.Account != null && (x.Account.Name ?? "").ToLower().Contains(s)) ||
|
||||
(x.Employee != null &&
|
||||
(((x.Employee.FirstName ?? "") + " " + (x.Employee.LastName ?? ""))
|
||||
.ToLower().Contains(s))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
var items = await query
|
||||
.OrderByDescending(f => f.CreatedDate)
|
||||
.OrderByDescending(f => f.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
|
|
|||
|
|
@ -94,5 +94,39 @@ namespace SeaHaven.DataServices.Implementation
|
|||
{
|
||||
return await _context.Locations.CountAsync();
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<object> Items, int TotalCount)> GetAddressbookPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null)
|
||||
{
|
||||
search ??= "";
|
||||
|
||||
var query = _context.Locations.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
var s = search.ToLower();
|
||||
query = query.Where(w =>
|
||||
(w.Name ?? "").ToLower().Contains(s) ||
|
||||
(w.Title ?? "").ToLower().Contains(s));
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var data = await query
|
||||
.Select(n => new
|
||||
{
|
||||
n.Id,
|
||||
n.Name,
|
||||
n.Title
|
||||
})
|
||||
.OrderByDescending(d => d.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
||||
return (data, totalCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,15 @@ namespace SeaHaven.DataServices.Implementation
|
|||
return await _context.PMSchedules.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PMSchedules>> GetAllWithDetailsAsync()
|
||||
{
|
||||
return await _context.PMSchedules
|
||||
.Include(x => x.Asset)
|
||||
.Include(x => x.Location)
|
||||
.OrderByDescending(x => x.Id)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PMSchedules>> GetByLocationIdAsync(int locationId)
|
||||
{
|
||||
return await _context.PMSchedules
|
||||
|
|
|
|||
|
|
@ -30,15 +30,27 @@ namespace SeaHaven.DataServices.Implementation
|
|||
}
|
||||
|
||||
public async Task<(IEnumerable<Vendor> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null)
|
||||
{
|
||||
var query = _context.Vendors.AsQueryable();
|
||||
search ??= "";
|
||||
|
||||
var query = _context.Vendors.Where(v => v.IsActive);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
var s = search.ToLower();
|
||||
query = query.Where(v =>
|
||||
(v.CompanyName ?? "").ToLower().Contains(s) ||
|
||||
(v.ContactName ?? "").ToLower().Contains(s) ||
|
||||
(v.Email ?? "").ToLower().Contains(s) ||
|
||||
(v.TradeSpecialties ?? "").ToLower().Contains(s));
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
var items = await query
|
||||
.OrderBy(v => v.Id)
|
||||
.OrderByDescending(v => v.Id)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToListAsync();
|
||||
|
|
|
|||
|
|
@ -66,18 +66,18 @@ namespace SeaHaven.DataServices.Implementation
|
|||
}
|
||||
|
||||
public async Task<(IEnumerable<WorkOrder> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
string? status = null,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
string? status = null,
|
||||
string? priority = null)
|
||||
{
|
||||
var query = _context.workOrders.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
query = query.Where(w =>
|
||||
w.WorkerOrderNumber!.Contains(search) ||
|
||||
query = query.Where(w =>
|
||||
w.WorkerOrderNumber!.Contains(search) ||
|
||||
w.WorkerOrderTitle!.Contains(search));
|
||||
}
|
||||
|
||||
|
|
@ -101,6 +101,91 @@ namespace SeaHaven.DataServices.Implementation
|
|||
return (items, totalCount);
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<object> Items, int TotalCount)> GetWorkOrderListPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
string? status = null,
|
||||
string? assignee = null,
|
||||
int? locationId = null,
|
||||
string? sortBy = "lastUpdated",
|
||||
string? sortDir = "desc")
|
||||
{
|
||||
search ??= "";
|
||||
|
||||
var query = _context.workOrders
|
||||
.Include(w => w.Locations)
|
||||
.Include(w => w.AssignToUser)
|
||||
.Where(w => w.istemplate != true);
|
||||
|
||||
if (locationId.HasValue)
|
||||
query = query.Where(w => w.LocationId == locationId.Value);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
query = query.Where(w => w.Status == status);
|
||||
|
||||
if (assignee == "__unassigned")
|
||||
query = query.Where(w => w.AssignTo == null || w.AssignTo == "");
|
||||
else if (!string.IsNullOrWhiteSpace(assignee))
|
||||
query = query.Where(w => w.AssignToUser != null && (w.AssignToUser.FirstName + " " + w.AssignToUser.LastName).Contains(assignee));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
var s = search.ToLower();
|
||||
query = query.Where(w =>
|
||||
(w.InternalWONumber ?? "").ToLower().Contains(s) ||
|
||||
(w.WorkerOrderNumber ?? "").ToLower().Contains(s) ||
|
||||
(w.WorkerOrderTitle ?? "").ToLower().Contains(s) ||
|
||||
(w.Locations.Title ?? "").ToLower().Contains(s) ||
|
||||
(w.Locations.Name ?? "").ToLower().Contains(s)
|
||||
);
|
||||
}
|
||||
|
||||
var totalCount = await query.CountAsync();
|
||||
|
||||
var isAsc = sortDir?.ToLower() == "asc";
|
||||
IOrderedQueryable<WorkOrder> ordered = (sortBy?.ToLower()) switch
|
||||
{
|
||||
"number" => isAsc ? query.OrderBy(w => w.InternalWONumber) : query.OrderByDescending(w => w.InternalWONumber),
|
||||
"title" => isAsc ? query.OrderBy(w => w.WorkerOrderTitle) : query.OrderByDescending(w => w.WorkerOrderTitle),
|
||||
"location" => isAsc ? query.OrderBy(w => w.Locations != null ? w.Locations.Name : "") : query.OrderByDescending(w => w.Locations != null ? w.Locations.Name : ""),
|
||||
"priority" => isAsc ? query.OrderBy(w => w.Priority) : query.OrderByDescending(w => w.Priority),
|
||||
"status" => isAsc ? query.OrderBy(w => w.Status) : query.OrderByDescending(w => w.Status),
|
||||
"createddate" => isAsc ? query.OrderBy(w => w.CreatedDate) : query.OrderByDescending(w => w.CreatedDate),
|
||||
"assignedto" => isAsc ? query.OrderBy(w => w.AssignToUser != null ? w.AssignToUser.FirstName : "") : query.OrderByDescending(w => w.AssignToUser != null ? w.AssignToUser.FirstName : ""),
|
||||
"lastupdated" => isAsc ? query.OrderBy(w => w.LastModificationTime) : query.OrderByDescending(w => w.LastModificationTime),
|
||||
_ => query.OrderByDescending(w => w.Id)
|
||||
};
|
||||
|
||||
var data = await ordered
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(w => new
|
||||
{
|
||||
id = w.Id,
|
||||
internalWONumber = w.InternalWONumber,
|
||||
workOrderNumber = w.WorkerOrderNumber,
|
||||
number = w.InternalWONumber ?? w.WorkerOrderNumber,
|
||||
title = w.WorkerOrderTitle,
|
||||
location = w.Locations != null ? w.Locations.Name : "",
|
||||
locationName = w.Locations != null ? w.Locations.Name : "",
|
||||
priority = w.Priority,
|
||||
status = w.Status,
|
||||
createdDate = w.CreatedDate,
|
||||
dueDate = w.DueDate,
|
||||
assignedTo = w.AssignToUser != null ? w.AssignToUser.FirstName + " " + w.AssignToUser.LastName : "",
|
||||
employeeName = w.AssignToUser != null ? w.AssignToUser.FirstName + " " + w.AssignToUser.LastName : "",
|
||||
lastUpdated = new[] {
|
||||
w.LastModificationTime,
|
||||
w.Comments.Max(c => (DateTime?)c.CreatedDate),
|
||||
_context.WorkOrderAuditLogs.Where(a => a.WorkOrderId == w.Id).Max(a => (DateTime?)a.CreatedAt)
|
||||
}.Where(d => d.HasValue).Max()
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
return (data, totalCount);
|
||||
}
|
||||
|
||||
public async Task<WorkOrder> AddAsync(WorkOrder workOrder)
|
||||
{
|
||||
workOrder.CreatedDate = DateTime.Now;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,13 @@ namespace SeaHaven.DataServices.Interfaces
|
|||
Task<Locations?> GetByIdWithDetailsAsync(int id);
|
||||
Task<IEnumerable<Locations>> GetAllAsync();
|
||||
Task<IEnumerable<Locations>> GetByAccountIdAsync(int accountId);
|
||||
|
||||
// Paged results returning DTOs
|
||||
Task<(IEnumerable<Locations> Items, int TotalCount)> GetPagedAsync(int page, int pageSize, string? search = null);
|
||||
|
||||
// For addressbook endpoint - returns simplified DTO
|
||||
Task<(IEnumerable<object> Items, int TotalCount)> GetAddressbookPagedAsync(int page, int pageSize, string? search = null);
|
||||
|
||||
Task<Locations> AddAsync(Locations location);
|
||||
Task UpdateAsync(Locations location);
|
||||
Task DeleteAsync(int id);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace SeaHaven.DataServices.Interfaces
|
|||
Task<PMSchedules?> GetByIdAsync(int id);
|
||||
Task<PMSchedules?> GetByIdWithDetailsAsync(int id);
|
||||
Task<IEnumerable<PMSchedules>> GetAllAsync();
|
||||
Task<IEnumerable<PMSchedules>> GetAllWithDetailsAsync();
|
||||
Task<IEnumerable<PMSchedules>> GetByLocationIdAsync(int locationId);
|
||||
Task<(IEnumerable<PMSchedules> Items, int TotalCount)> GetPagedAsync(int page, int pageSize, string? search = null);
|
||||
Task<PMSchedules> AddAsync(PMSchedules pmSchedule);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,22 @@ namespace SeaHaven.DataServices.Interfaces
|
|||
|
||||
// Paged results
|
||||
Task<(IEnumerable<WorkOrder> Items, int TotalCount)> GetPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
string? status = null,
|
||||
string? priority = null);
|
||||
|
||||
// Paged list with detailed information (for GetWorkOrderList endpoint)
|
||||
Task<(IEnumerable<object> Items, int TotalCount)> GetWorkOrderListPagedAsync(
|
||||
int page,
|
||||
int pageSize,
|
||||
string? search = null,
|
||||
string? status = null,
|
||||
string? assignee = null,
|
||||
int? locationId = null,
|
||||
string? sortBy = "lastUpdated",
|
||||
string? sortDir = "desc");
|
||||
|
||||
// Command operations
|
||||
Task<WorkOrder> AddAsync(WorkOrder workOrder);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace SeaHaven.Services.DTOs
|
|||
{
|
||||
public int Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Type { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? Website { get; set; }
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ namespace SeaHaven.Services.DTOs
|
|||
{
|
||||
public int Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Type { get; set; }
|
||||
public string? SerialNumber { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
public string? LocationName { get; set; }
|
||||
public DateTime? CreatedDate { get; set; }
|
||||
|
|
@ -14,16 +12,12 @@ namespace SeaHaven.Services.DTOs
|
|||
public class CreateAssetDTO
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public string? Type { get; set; }
|
||||
public string? SerialNumber { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateAssetDTO
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public string? Type { get; set; }
|
||||
public string? SerialNumber { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,32 +3,41 @@ namespace SeaHaven.Services.DTOs
|
|||
public class FollowUpDTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string? Subject { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Reason { get; set; }
|
||||
public DateTime ScheduleDate { get; set; }
|
||||
public TimeSpan ScheduleStartTime { get; set; }
|
||||
public string? Status { get; set; }
|
||||
public int? EmployeeId { get; set; }
|
||||
public string? EmployeeName { get; set; }
|
||||
public int? WorkOrderId { get; set; }
|
||||
public string? AssignedTo { get; set; }
|
||||
public DateTime? DueDate { get; set; }
|
||||
public int? AccountId { get; set; }
|
||||
public string? AccountName { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
public string? LocationName { get; set; }
|
||||
public DateTime? CreatedDate { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
}
|
||||
|
||||
public class CreateFollowUpDTO
|
||||
{
|
||||
public required string Subject { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Status { get; set; }
|
||||
public required string Reason { get; set; }
|
||||
public DateTime ScheduleDate { get; set; }
|
||||
public TimeSpan ScheduleStartTime { get; set; }
|
||||
public required string Status { get; set; }
|
||||
public int? EmployeeId { get; set; }
|
||||
public int? WorkOrderId { get; set; }
|
||||
public string? AssignedTo { get; set; }
|
||||
public DateTime? DueDate { get; set; }
|
||||
public int? AccountId { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateFollowUpDTO
|
||||
{
|
||||
public string? Subject { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Reason { get; set; }
|
||||
public DateTime? ScheduleDate { get; set; }
|
||||
public TimeSpan? ScheduleStartTime { get; set; }
|
||||
public string? Status { get; set; }
|
||||
public string? AssignedTo { get; set; }
|
||||
public DateTime? DueDate { get; set; }
|
||||
public int? EmployeeId { get; set; }
|
||||
public int? WorkOrderId { get; set; }
|
||||
public int? AccountId { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,16 @@ namespace SeaHaven.Services.DTOs
|
|||
public class LocationDTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string? LocationName { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Title { get; set; }
|
||||
public string? Address1 { get; set; }
|
||||
public string? Address2 { get; set; }
|
||||
public string? City { get; set; }
|
||||
public string? State { get; set; }
|
||||
public string? Zipcode { get; set; }
|
||||
public int? AccountId { get; set; }
|
||||
public string? AccountName { get; set; }
|
||||
public string? Zip { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? Status { get; set; }
|
||||
public DateTime? CreatedDate { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,29 +4,33 @@ namespace SeaHaven.Services.DTOs
|
|||
{
|
||||
public int Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Frequency { get; set; }
|
||||
public DateTime StartDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public int? AssetId { get; set; }
|
||||
public string? AssetName { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
public string? LocationName { get; set; }
|
||||
public string? Frequency { get; set; }
|
||||
public DateTime? NextDueDate { get; set; }
|
||||
public DateTime? CreatedDate { get; set; }
|
||||
}
|
||||
|
||||
public class CreatePMScheduleDTO
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public required string Frequency { get; set; }
|
||||
public DateTime StartDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public int? AssetId { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
public string? Frequency { get; set; }
|
||||
public DateTime? NextDueDate { get; set; }
|
||||
}
|
||||
|
||||
public class UpdatePMScheduleDTO
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
public string? Frequency { get; set; }
|
||||
public DateTime? NextDueDate { get; set; }
|
||||
public DateTime? StartDate { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
public int? AssetId { get; set; }
|
||||
public int? LocationId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
124
SeaHaven.Services/Implementation/AccountService.cs
Normal file
124
SeaHaven.Services/Implementation/AccountService.cs
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Account service implementation
|
||||
/// Contains business logic, validation, and orchestration for Account operations
|
||||
/// </summary>
|
||||
public class AccountService : IAccountService
|
||||
{
|
||||
private readonly IAccountDataService _accountDataService;
|
||||
|
||||
public AccountService(IAccountDataService accountDataService)
|
||||
{
|
||||
_accountDataService = accountDataService;
|
||||
}
|
||||
|
||||
public async Task<AccountDTO?> GetAccountByIdAsync(int id)
|
||||
{
|
||||
var account = await _accountDataService.GetByIdAsync(id);
|
||||
return account == null ? null : MapToDTO(account);
|
||||
}
|
||||
|
||||
public async Task<AccountDTO?> GetAccountByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var account = await _accountDataService.GetByIdWithDetailsAsync(id);
|
||||
return account == null ? null : MapToDTO(account);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AccountDTO>> GetAllAccountsAsync()
|
||||
{
|
||||
var accounts = await _accountDataService.GetAllAsync();
|
||||
return accounts.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<AccountDTO>> GetAccountsPagedAsync(int page, int pageSize, string? search = null)
|
||||
{
|
||||
var (items, totalCount) = await _accountDataService.GetPagedAsync(page, pageSize, search);
|
||||
return new PagedResult<AccountDTO>
|
||||
{
|
||||
Items = items.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<AccountDTO> CreateAccountAsync(CreateAccountDTO dto, string userId)
|
||||
{
|
||||
var account = new Accounts
|
||||
{
|
||||
Name = dto.Name,
|
||||
Phone = dto.Phone,
|
||||
Email = dto.Email,
|
||||
Website = dto.Website,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
createdby = userId
|
||||
};
|
||||
|
||||
var created = await _accountDataService.AddAsync(account);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<AccountDTO> UpdateAccountAsync(int id, UpdateAccountDTO dto, string userId)
|
||||
{
|
||||
var account = await _accountDataService.GetByIdAsync(id);
|
||||
if (account == null)
|
||||
throw new InvalidOperationException($"Account with ID {id} not found");
|
||||
|
||||
if (dto.Name != null) account.Name = dto.Name;
|
||||
if (dto.Phone != null) account.Phone = dto.Phone;
|
||||
if (dto.Email != null) account.Email = dto.Email;
|
||||
if (dto.Website != null) account.Website = dto.Website;
|
||||
|
||||
account.LastModificationTime = DateTime.UtcNow;
|
||||
if (int.TryParse(userId, out int userIdInt))
|
||||
account.LastModifierUserId = userIdInt;
|
||||
|
||||
await _accountDataService.UpdateAsync(account);
|
||||
return MapToDTO(account);
|
||||
}
|
||||
|
||||
public async Task DeleteAccountAsync(int id, string userId)
|
||||
{
|
||||
var account = await _accountDataService.GetByIdAsync(id);
|
||||
if (account == null)
|
||||
throw new InvalidOperationException($"Account with ID {id} not found");
|
||||
|
||||
account.IsDeleted = true;
|
||||
account.DeleterUserId = userId;
|
||||
account.DeletionTime = DateTime.UtcNow;
|
||||
|
||||
await _accountDataService.UpdateAsync(account);
|
||||
}
|
||||
|
||||
public async Task<bool> AccountExistsAsync(int id)
|
||||
{
|
||||
return await _accountDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalAccountCountAsync()
|
||||
{
|
||||
return await _accountDataService.CountAsync();
|
||||
}
|
||||
|
||||
private AccountDTO MapToDTO(Accounts account)
|
||||
{
|
||||
return new AccountDTO
|
||||
{
|
||||
Id = account.Id,
|
||||
Name = account.Name,
|
||||
Type = account.Type,
|
||||
Phone = account.Phone,
|
||||
Email = account.Email,
|
||||
Website = account.Website,
|
||||
CreatedDate = account.CreatedDate,
|
||||
CreatedBy = account.createdby
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
123
SeaHaven.Services/Implementation/AssetService.cs
Normal file
123
SeaHaven.Services/Implementation/AssetService.cs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Asset service implementation
|
||||
/// Contains business logic, validation, and orchestration for Asset operations
|
||||
/// </summary>
|
||||
public class AssetService : IAssetService
|
||||
{
|
||||
private readonly IAssetDataService _assetDataService;
|
||||
|
||||
public AssetService(IAssetDataService assetDataService)
|
||||
{
|
||||
_assetDataService = assetDataService;
|
||||
}
|
||||
|
||||
public async Task<AssetDTO?> GetAssetByIdAsync(int id)
|
||||
{
|
||||
var asset = await _assetDataService.GetByIdAsync(id);
|
||||
return asset == null ? null : MapToDTO(asset);
|
||||
}
|
||||
|
||||
public async Task<AssetDTO?> GetAssetByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var asset = await _assetDataService.GetByIdWithDetailsAsync(id);
|
||||
return asset == null ? null : MapToDTO(asset);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AssetDTO>> GetAllAssetsAsync()
|
||||
{
|
||||
var assets = await _assetDataService.GetAllAsync();
|
||||
return assets.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<AssetDTO>> GetAssetsByLocationIdAsync(int locationId)
|
||||
{
|
||||
var assets = await _assetDataService.GetAllAsync();
|
||||
return assets.Where(a => a.LocationId == locationId).Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<AssetDTO>> GetAssetsPagedAsync(int page, int pageSize, string? search = null)
|
||||
{
|
||||
var (items, totalCount) = await _assetDataService.GetPagedAsync(page, pageSize, search);
|
||||
return new PagedResult<AssetDTO>
|
||||
{
|
||||
Items = items.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<AssetDTO> CreateAssetAsync(CreateAssetDTO dto, string userId)
|
||||
{
|
||||
var asset = new Assets
|
||||
{
|
||||
Name = dto.Name,
|
||||
LocationId = dto.LocationId,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
createdby = userId
|
||||
};
|
||||
|
||||
var created = await _assetDataService.AddAsync(asset);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<AssetDTO> UpdateAssetAsync(int id, UpdateAssetDTO dto, string userId)
|
||||
{
|
||||
var asset = await _assetDataService.GetByIdAsync(id);
|
||||
if (asset == null)
|
||||
throw new InvalidOperationException($"Asset with ID {id} not found");
|
||||
|
||||
if (dto.Name != null) asset.Name = dto.Name;
|
||||
if (dto.LocationId.HasValue) asset.LocationId = dto.LocationId;
|
||||
|
||||
asset.LastModificationTime = DateTime.UtcNow;
|
||||
if (int.TryParse(userId, out int userIdInt))
|
||||
asset.LastModifierUserId = userIdInt;
|
||||
|
||||
await _assetDataService.UpdateAsync(asset);
|
||||
return MapToDTO(asset);
|
||||
}
|
||||
|
||||
public async Task DeleteAssetAsync(int id, string userId)
|
||||
{
|
||||
var asset = await _assetDataService.GetByIdAsync(id);
|
||||
if (asset == null)
|
||||
throw new InvalidOperationException($"Asset with ID {id} not found");
|
||||
|
||||
asset.IsDeleted = true;
|
||||
asset.DeleterUserId = userId;
|
||||
asset.DeletionTime = DateTime.UtcNow;
|
||||
|
||||
await _assetDataService.UpdateAsync(asset);
|
||||
}
|
||||
|
||||
public async Task<bool> AssetExistsAsync(int id)
|
||||
{
|
||||
return await _assetDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalAssetCountAsync()
|
||||
{
|
||||
return await _assetDataService.CountAsync();
|
||||
}
|
||||
|
||||
private AssetDTO MapToDTO(Assets asset)
|
||||
{
|
||||
return new AssetDTO
|
||||
{
|
||||
Id = asset.Id,
|
||||
Name = asset.Name,
|
||||
LocationId = asset.LocationId,
|
||||
LocationName = asset.Location?.Name,
|
||||
CreatedDate = asset.CreatedDate
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
139
SeaHaven.Services/Implementation/DispatchService.cs
Normal file
139
SeaHaven.Services/Implementation/DispatchService.cs
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Dispatch service implementation
|
||||
/// Contains business logic, validation, and orchestration for Dispatch operations
|
||||
/// </summary>
|
||||
public class DispatchService : IDispatchService
|
||||
{
|
||||
private readonly IDispatchDataService _dispatchDataService;
|
||||
|
||||
public DispatchService(IDispatchDataService dispatchDataService)
|
||||
{
|
||||
_dispatchDataService = dispatchDataService;
|
||||
}
|
||||
|
||||
public async Task<DispatchDTO?> GetDispatchByIdAsync(int id)
|
||||
{
|
||||
var dispatch = await _dispatchDataService.GetByIdAsync(id);
|
||||
return dispatch == null ? null : MapToDTO(dispatch);
|
||||
}
|
||||
|
||||
public async Task<DispatchDTO?> GetDispatchByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var dispatch = await _dispatchDataService.GetByIdWithDetailsAsync(id);
|
||||
return dispatch == null ? null : MapToDTO(dispatch);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DispatchDTO>> GetAllDispatchesAsync()
|
||||
{
|
||||
var dispatches = await _dispatchDataService.GetAllAsync();
|
||||
return dispatches.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<DispatchDTO>> GetDispatchesByVendorIdAsync(int vendorId)
|
||||
{
|
||||
var dispatches = await _dispatchDataService.GetByVendorIdAsync(vendorId);
|
||||
return dispatches.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<DispatchDTO>> GetDispatchesPagedAsync(int page, int pageSize, string? search = null, string? status = null)
|
||||
{
|
||||
var (items, totalCount) = await _dispatchDataService.GetPagedAsync(page, pageSize, search, status);
|
||||
return new PagedResult<DispatchDTO>
|
||||
{
|
||||
Items = items.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<DispatchDTO> CreateDispatchAsync(CreateDispatchDTO dto, string userId)
|
||||
{
|
||||
var dispatchNumber = await GenerateNextDispatchNumberAsync();
|
||||
|
||||
var dispatch = new Dispatch
|
||||
{
|
||||
VendorId = dto.VendorId,
|
||||
ScheduledDate = dto.ScheduledDate,
|
||||
Status = dto.Status ?? "Pending",
|
||||
DispatchNumber = dispatchNumber,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
createdby = userId
|
||||
};
|
||||
|
||||
var created = await _dispatchDataService.AddAsync(dispatch);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<DispatchDTO> UpdateDispatchAsync(int id, UpdateDispatchDTO dto, string userId)
|
||||
{
|
||||
var dispatch = await _dispatchDataService.GetByIdAsync(id);
|
||||
if (dispatch == null)
|
||||
throw new InvalidOperationException($"Dispatch with ID {id} not found");
|
||||
|
||||
if (dto.VendorId.HasValue) dispatch.VendorId = dto.VendorId.Value;
|
||||
if (dto.ScheduledDate.HasValue) dispatch.ScheduledDate = dto.ScheduledDate;
|
||||
if (dto.CompletedDate.HasValue) dispatch.CompletedDate = dto.CompletedDate;
|
||||
if (dto.Status != null) dispatch.Status = dto.Status;
|
||||
|
||||
dispatch.LastModificationTime = DateTime.UtcNow;
|
||||
if (int.TryParse(userId, out int userIdInt))
|
||||
dispatch.LastModifierUserId = userIdInt;
|
||||
|
||||
await _dispatchDataService.UpdateAsync(dispatch);
|
||||
return MapToDTO(dispatch);
|
||||
}
|
||||
|
||||
public async Task DeleteDispatchAsync(int id, string userId)
|
||||
{
|
||||
var dispatch = await _dispatchDataService.GetByIdAsync(id);
|
||||
if (dispatch == null)
|
||||
throw new InvalidOperationException($"Dispatch with ID {id} not found");
|
||||
|
||||
dispatch.IsDeleted = true;
|
||||
dispatch.DeleterUserId = userId;
|
||||
dispatch.DeletionTime = DateTime.UtcNow;
|
||||
|
||||
await _dispatchDataService.UpdateAsync(dispatch);
|
||||
}
|
||||
|
||||
public async Task<bool> DispatchExistsAsync(int id)
|
||||
{
|
||||
return await _dispatchDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<string> GenerateNextDispatchNumberAsync()
|
||||
{
|
||||
var count = await _dispatchDataService.CountAsync();
|
||||
return $"DISP-{(count + 1):D6}";
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalDispatchCountAsync()
|
||||
{
|
||||
return await _dispatchDataService.CountAsync();
|
||||
}
|
||||
|
||||
private DispatchDTO MapToDTO(Dispatch dispatch)
|
||||
{
|
||||
return new DispatchDTO
|
||||
{
|
||||
Id = dispatch.Id,
|
||||
DispatchNumber = dispatch.DispatchNumber,
|
||||
Status = dispatch.Status,
|
||||
VendorId = dispatch.VendorId,
|
||||
VendorName = dispatch.Vendor?.CompanyName,
|
||||
ScheduledDate = dispatch.ScheduledDate,
|
||||
CompletedDate = dispatch.CompletedDate,
|
||||
CreatedDate = dispatch.CreatedDate,
|
||||
CreatedBy = dispatch.createdby
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
149
SeaHaven.Services/Implementation/EmployeeService.cs
Normal file
149
SeaHaven.Services/Implementation/EmployeeService.cs
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Employee service implementation
|
||||
/// Contains business logic, validation, and orchestration for Employee operations
|
||||
/// </summary>
|
||||
public class EmployeeService : IEmployeeService
|
||||
{
|
||||
private readonly IEmployeeDataService _employeeDataService;
|
||||
|
||||
public EmployeeService(IEmployeeDataService employeeDataService)
|
||||
{
|
||||
_employeeDataService = employeeDataService;
|
||||
}
|
||||
|
||||
// Query operations
|
||||
public async Task<EmployeeDTO?> GetEmployeeByIdAsync(int id)
|
||||
{
|
||||
var employee = await _employeeDataService.GetByIdAsync(id);
|
||||
return employee == null ? null : MapToDTO(employee);
|
||||
}
|
||||
|
||||
public async Task<EmployeeDTO?> GetEmployeeByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var employee = await _employeeDataService.GetByIdWithDetailsAsync(id);
|
||||
return employee == null ? null : MapToDTO(employee);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<EmployeeDTO>> GetAllEmployeesAsync()
|
||||
{
|
||||
var employees = await _employeeDataService.GetAllAsync();
|
||||
return employees.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<EmployeeDTO>> GetEmployeesPagedAsync(int page, int pageSize, string? search = null)
|
||||
{
|
||||
var (items, totalCount) = await _employeeDataService.GetPagedAsync(page, pageSize, search);
|
||||
return new PagedResult<EmployeeDTO>
|
||||
{
|
||||
Items = items.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<EmployeeDTO> CreateEmployeeAsync(CreateEmployeeDTO dto, string userId)
|
||||
{
|
||||
var employee = new Employee
|
||||
{
|
||||
FirstName = dto.FirstName,
|
||||
LastName = dto.LastName,
|
||||
DepartmentId = dto.DepartmentId,
|
||||
JobTitleId = dto.JobTitleId,
|
||||
RegionId = dto.RegionId,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
CreatedBy = userId
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(dto.Email))
|
||||
{
|
||||
employee.Emails.Add(new EmployeeEmail
|
||||
{
|
||||
Address = dto.Email,
|
||||
IsPrimary = true
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(dto.Phone))
|
||||
{
|
||||
employee.Phones.Add(new EmployeePhone
|
||||
{
|
||||
Number = dto.Phone,
|
||||
IsPrimary = true
|
||||
});
|
||||
}
|
||||
|
||||
var created = await _employeeDataService.AddAsync(employee);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<EmployeeDTO> UpdateEmployeeAsync(int id, UpdateEmployeeDTO dto, string userId)
|
||||
{
|
||||
var employee = await _employeeDataService.GetByIdAsync(id);
|
||||
if (employee == null)
|
||||
throw new InvalidOperationException($"Employee with ID {id} not found");
|
||||
|
||||
if (dto.FirstName != null) employee.FirstName = dto.FirstName;
|
||||
if (dto.LastName != null) employee.LastName = dto.LastName;
|
||||
if (dto.DepartmentId.HasValue) employee.DepartmentId = dto.DepartmentId;
|
||||
if (dto.JobTitleId.HasValue) employee.JobTitleId = dto.JobTitleId;
|
||||
if (dto.RegionId.HasValue) employee.RegionId = dto.RegionId;
|
||||
|
||||
employee.LastModificationTime = DateTime.UtcNow;
|
||||
employee.LastModifierUserId = int.Parse(userId);
|
||||
|
||||
await _employeeDataService.UpdateAsync(employee);
|
||||
return MapToDTO(employee);
|
||||
}
|
||||
|
||||
public async Task DeleteEmployeeAsync(int id, string userId)
|
||||
{
|
||||
var employee = await _employeeDataService.GetByIdAsync(id);
|
||||
if (employee == null)
|
||||
throw new InvalidOperationException($"Employee with ID {id} not found");
|
||||
|
||||
employee.IsDeleted = true;
|
||||
employee.CreatedBy = userId;
|
||||
employee.LastModificationTime = DateTime.UtcNow;
|
||||
|
||||
await _employeeDataService.UpdateAsync(employee);
|
||||
}
|
||||
|
||||
public async Task<bool> EmployeeExistsAsync(int id)
|
||||
{
|
||||
return await _employeeDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalEmployeeCountAsync()
|
||||
{
|
||||
return await _employeeDataService.CountAsync();
|
||||
}
|
||||
|
||||
// Private helper methods
|
||||
private EmployeeDTO MapToDTO(Employee employee)
|
||||
{
|
||||
return new EmployeeDTO
|
||||
{
|
||||
Id = employee.Id,
|
||||
FirstName = employee.FirstName,
|
||||
LastName = employee.LastName,
|
||||
Email = employee.Emails?.FirstOrDefault(e => e.IsPrimary == true)?.Address,
|
||||
Phone = employee.Phones?.FirstOrDefault(p => p.IsPrimary == true)?.Number,
|
||||
DepartmentId = employee.DepartmentId,
|
||||
DepartmentName = employee.Department?.Name,
|
||||
JobTitleId = employee.JobTitleId,
|
||||
JobTitleName = employee.JobTitle?.Name,
|
||||
RegionId = employee.RegionId,
|
||||
RegionName = employee.Region?.Name,
|
||||
CreatedDate = employee.CreatedDate
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
150
SeaHaven.Services/Implementation/FollowUpService.cs
Normal file
150
SeaHaven.Services/Implementation/FollowUpService.cs
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Follow-Up service implementation
|
||||
/// Contains business logic, validation, and orchestration for Follow-Up operations
|
||||
/// </summary>
|
||||
public class FollowUpService : IFollowUpService
|
||||
{
|
||||
private readonly IFollowUpDataService _followUpDataService;
|
||||
|
||||
public FollowUpService(IFollowUpDataService followUpDataService)
|
||||
{
|
||||
_followUpDataService = followUpDataService;
|
||||
}
|
||||
|
||||
public async Task<FollowUpDTO?> GetFollowUpByIdAsync(int id)
|
||||
{
|
||||
var followUp = await _followUpDataService.GetByIdAsync(id);
|
||||
return followUp == null ? null : MapToDTO(followUp);
|
||||
}
|
||||
|
||||
public async Task<FollowUpDTO?> GetFollowUpByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var followUp = await _followUpDataService.GetByIdWithDetailsAsync(id);
|
||||
return followUp == null ? null : MapToDTO(followUp);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<FollowUpDTO>> GetAllFollowUpsAsync()
|
||||
{
|
||||
var followUps = await _followUpDataService.GetAllAsync();
|
||||
return followUps.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<FollowUpDTO>> GetFollowUpsByWorkOrderIdAsync(int workOrderId)
|
||||
{
|
||||
var followUps = await _followUpDataService.GetByWorkOrderIdAsync(workOrderId);
|
||||
return followUps.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<FollowUpDTO>> GetFollowUpsPagedAsync(int page, int pageSize, string? search = null, string? status = null)
|
||||
{
|
||||
var (items, totalCount) = await _followUpDataService.GetPagedAsync(page, pageSize, search);
|
||||
|
||||
var filteredItems = items.AsEnumerable();
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
{
|
||||
filteredItems = filteredItems.Where(f => f.Status == status);
|
||||
}
|
||||
|
||||
return new PagedResult<FollowUpDTO>
|
||||
{
|
||||
Items = filteredItems.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<FollowUpDTO> CreateFollowUpAsync(CreateFollowUpDTO dto, string userId)
|
||||
{
|
||||
var followUp = new FollowUps
|
||||
{
|
||||
Reason = dto.Reason,
|
||||
ScheduleDate = dto.ScheduleDate,
|
||||
ScheduleStartTime = dto.ScheduleStartTime,
|
||||
Status = dto.Status,
|
||||
EmployeeId = dto.EmployeeId,
|
||||
WorkOrderId = dto.WorkOrderId,
|
||||
AccountId = dto.AccountId,
|
||||
LocationId = dto.LocationId,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
createdby = userId
|
||||
};
|
||||
|
||||
var created = await _followUpDataService.AddAsync(followUp);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<FollowUpDTO> UpdateFollowUpAsync(int id, UpdateFollowUpDTO dto, string userId)
|
||||
{
|
||||
var followUp = await _followUpDataService.GetByIdAsync(id);
|
||||
if (followUp == null)
|
||||
throw new InvalidOperationException($"Follow-Up with ID {id} not found");
|
||||
|
||||
if (dto.Reason != null) followUp.Reason = dto.Reason;
|
||||
if (dto.ScheduleDate.HasValue) followUp.ScheduleDate = dto.ScheduleDate.Value;
|
||||
if (dto.ScheduleStartTime.HasValue) followUp.ScheduleStartTime = dto.ScheduleStartTime.Value;
|
||||
if (dto.Status != null) followUp.Status = dto.Status;
|
||||
if (dto.EmployeeId.HasValue) followUp.EmployeeId = dto.EmployeeId;
|
||||
if (dto.WorkOrderId.HasValue) followUp.WorkOrderId = dto.WorkOrderId;
|
||||
if (dto.AccountId.HasValue) followUp.AccountId = dto.AccountId;
|
||||
if (dto.LocationId.HasValue) followUp.LocationId = dto.LocationId;
|
||||
|
||||
followUp.LastModificationTime = DateTime.UtcNow;
|
||||
if (int.TryParse(userId, out int userIdInt))
|
||||
followUp.LastModifierUserId = userIdInt;
|
||||
|
||||
await _followUpDataService.UpdateAsync(followUp);
|
||||
return MapToDTO(followUp);
|
||||
}
|
||||
|
||||
public async Task DeleteFollowUpAsync(int id, string userId)
|
||||
{
|
||||
var followUp = await _followUpDataService.GetByIdAsync(id);
|
||||
if (followUp == null)
|
||||
throw new InvalidOperationException($"Follow-Up with ID {id} not found");
|
||||
|
||||
followUp.IsDeleted = true;
|
||||
followUp.DeleterUserId = userId;
|
||||
followUp.DeletionTime = DateTime.UtcNow;
|
||||
|
||||
await _followUpDataService.UpdateAsync(followUp);
|
||||
}
|
||||
|
||||
public async Task<bool> FollowUpExistsAsync(int id)
|
||||
{
|
||||
return await _followUpDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalFollowUpCountAsync()
|
||||
{
|
||||
return await _followUpDataService.CountAsync();
|
||||
}
|
||||
|
||||
private FollowUpDTO MapToDTO(FollowUps followUp)
|
||||
{
|
||||
return new FollowUpDTO
|
||||
{
|
||||
Id = followUp.Id,
|
||||
Reason = followUp.Reason,
|
||||
ScheduleDate = followUp.ScheduleDate,
|
||||
ScheduleStartTime = followUp.ScheduleStartTime,
|
||||
Status = followUp.Status,
|
||||
EmployeeId = followUp.EmployeeId,
|
||||
EmployeeName = followUp.Employee != null ? $"{followUp.Employee.FirstName} {followUp.Employee.LastName}" : null,
|
||||
WorkOrderId = followUp.WorkOrderId,
|
||||
AccountId = followUp.AccountId,
|
||||
AccountName = followUp.Account?.Name,
|
||||
LocationId = followUp.LocationId,
|
||||
LocationName = followUp.Location?.Name,
|
||||
CreatedDate = followUp.CreatedDate
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
142
SeaHaven.Services/Implementation/LocationService.cs
Normal file
142
SeaHaven.Services/Implementation/LocationService.cs
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Location service implementation
|
||||
/// Contains business logic, validation, and orchestration for Location operations
|
||||
/// </summary>
|
||||
public class LocationService : ILocationService
|
||||
{
|
||||
private readonly ILocationDataService _locationDataService;
|
||||
|
||||
public LocationService(ILocationDataService locationDataService)
|
||||
{
|
||||
_locationDataService = locationDataService;
|
||||
}
|
||||
|
||||
// Query operations
|
||||
public async Task<LocationDTO?> GetLocationByIdAsync(int id)
|
||||
{
|
||||
var location = await _locationDataService.GetByIdAsync(id);
|
||||
return location == null ? null : MapToDTO(location);
|
||||
}
|
||||
|
||||
public async Task<LocationDTO?> GetLocationByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var location = await _locationDataService.GetByIdWithDetailsAsync(id);
|
||||
return location == null ? null : MapToDTO(location);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LocationDTO>> GetAllLocationsAsync()
|
||||
{
|
||||
var locations = await _locationDataService.GetAllAsync();
|
||||
return locations.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LocationDTO>> GetLocationsByAccountIdAsync(int accountId)
|
||||
{
|
||||
var locations = await _locationDataService.GetByAccountIdAsync(accountId);
|
||||
return locations.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<LocationDTO>> GetLocationsPagedAsync(int page, int pageSize, string? search = null)
|
||||
{
|
||||
var (items, totalCount) = await _locationDataService.GetPagedAsync(page, pageSize, search);
|
||||
return new PagedResult<LocationDTO>
|
||||
{
|
||||
Items = items.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<LocationDTO> CreateLocationAsync(CreateLocationDTO dto, string userId)
|
||||
{
|
||||
var location = new Locations
|
||||
{
|
||||
Name = dto.LocationName,
|
||||
Title = dto.LocationName,
|
||||
Address1 = dto.Address,
|
||||
City = dto.City,
|
||||
State = dto.State,
|
||||
Zip = dto.Zipcode,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
createdby = userId
|
||||
};
|
||||
|
||||
var created = await _locationDataService.AddAsync(location);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<LocationDTO> UpdateLocationAsync(int id, UpdateLocationDTO dto, string userId)
|
||||
{
|
||||
var location = await _locationDataService.GetByIdAsync(id);
|
||||
if (location == null)
|
||||
throw new InvalidOperationException($"Location with ID {id} not found");
|
||||
|
||||
// Update properties
|
||||
if (dto.LocationName != null) location.Name = dto.LocationName;
|
||||
if (dto.LocationName != null) location.Title = dto.LocationName;
|
||||
if (dto.Address != null) location.Address1 = dto.Address;
|
||||
if (dto.City != null) location.City = dto.City;
|
||||
if (dto.State != null) location.State = dto.State;
|
||||
if (dto.Zipcode != null) location.Zip = dto.Zipcode;
|
||||
|
||||
location.LastModificationTime = DateTime.UtcNow;
|
||||
if (int.TryParse(userId, out int userIdInt))
|
||||
location.LastModifierUserId = userIdInt;
|
||||
|
||||
await _locationDataService.UpdateAsync(location);
|
||||
return MapToDTO(location);
|
||||
}
|
||||
|
||||
public async Task DeleteLocationAsync(int id, string userId)
|
||||
{
|
||||
var location = await _locationDataService.GetByIdAsync(id);
|
||||
if (location == null)
|
||||
throw new InvalidOperationException($"Location with ID {id} not found");
|
||||
|
||||
location.IsDeleted = true;
|
||||
location.DeleterUserId = userId;
|
||||
location.DeletionTime = DateTime.UtcNow;
|
||||
|
||||
await _locationDataService.UpdateAsync(location);
|
||||
}
|
||||
|
||||
public async Task<bool> LocationExistsAsync(int id)
|
||||
{
|
||||
return await _locationDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalLocationCountAsync()
|
||||
{
|
||||
return await _locationDataService.CountAsync();
|
||||
}
|
||||
|
||||
// Private helper methods
|
||||
private LocationDTO MapToDTO(Locations location)
|
||||
{
|
||||
return new LocationDTO
|
||||
{
|
||||
Id = location.Id,
|
||||
Name = location.Name,
|
||||
Title = location.Title,
|
||||
Address1 = location.Address1,
|
||||
Address2 = location.Address2,
|
||||
City = location.City,
|
||||
State = location.State,
|
||||
Zip = location.Zip,
|
||||
PhoneNumber = location.PhoneNumber,
|
||||
Email = location.Email,
|
||||
Status = location.Status,
|
||||
CreatedDate = location.CreatedDate,
|
||||
CreatedBy = location.createdby
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
136
SeaHaven.Services/Implementation/PMScheduleService.cs
Normal file
136
SeaHaven.Services/Implementation/PMScheduleService.cs
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// PM Schedule service implementation
|
||||
/// Contains business logic, validation, and orchestration for PM Schedule operations
|
||||
/// </summary>
|
||||
public class PMScheduleService : IPMScheduleService
|
||||
{
|
||||
private readonly IPMScheduleDataService _pmScheduleDataService;
|
||||
|
||||
public PMScheduleService(IPMScheduleDataService pmScheduleDataService)
|
||||
{
|
||||
_pmScheduleDataService = pmScheduleDataService;
|
||||
}
|
||||
|
||||
public async Task<PMScheduleDTO?> GetPMScheduleByIdAsync(int id)
|
||||
{
|
||||
var pmSchedule = await _pmScheduleDataService.GetByIdAsync(id);
|
||||
return pmSchedule == null ? null : MapToDTO(pmSchedule);
|
||||
}
|
||||
|
||||
public async Task<PMScheduleDTO?> GetPMScheduleByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var pmSchedule = await _pmScheduleDataService.GetByIdWithDetailsAsync(id);
|
||||
return pmSchedule == null ? null : MapToDTO(pmSchedule);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PMScheduleDTO>> GetAllPMSchedulesAsync()
|
||||
{
|
||||
var pmSchedules = await _pmScheduleDataService.GetAllWithDetailsAsync();
|
||||
return pmSchedules.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PMScheduleDTO>> GetPMSchedulesByLocationIdAsync(int locationId)
|
||||
{
|
||||
var pmSchedules = await _pmScheduleDataService.GetAllWithDetailsAsync();
|
||||
return pmSchedules.Where(p => p.LocationId == locationId).Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<PMScheduleDTO>> GetPMSchedulesPagedAsync(int page, int pageSize, string? search = null)
|
||||
{
|
||||
var (items, totalCount) = await _pmScheduleDataService.GetPagedAsync(page, pageSize, search);
|
||||
return new PagedResult<PMScheduleDTO>
|
||||
{
|
||||
Items = items.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<PMScheduleDTO> CreatePMScheduleAsync(CreatePMScheduleDTO dto, string userId)
|
||||
{
|
||||
var pmSchedule = new PMSchedules
|
||||
{
|
||||
Name = dto.Name,
|
||||
Frequency = dto.Frequency,
|
||||
StartDate = dto.StartDate,
|
||||
IsActive = dto.IsActive,
|
||||
AssetId = dto.AssetId,
|
||||
LocationId = dto.LocationId,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
createdby = userId
|
||||
};
|
||||
|
||||
var created = await _pmScheduleDataService.AddAsync(pmSchedule);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<PMScheduleDTO> UpdatePMScheduleAsync(int id, UpdatePMScheduleDTO dto, string userId)
|
||||
{
|
||||
var pmSchedule = await _pmScheduleDataService.GetByIdAsync(id);
|
||||
if (pmSchedule == null)
|
||||
throw new InvalidOperationException($"PM Schedule with ID {id} not found");
|
||||
|
||||
if (dto.Name != null) pmSchedule.Name = dto.Name;
|
||||
if (dto.Frequency != null) pmSchedule.Frequency = dto.Frequency;
|
||||
if (dto.StartDate.HasValue) pmSchedule.StartDate = dto.StartDate.Value;
|
||||
if (dto.IsActive.HasValue) pmSchedule.IsActive = dto.IsActive.Value;
|
||||
if (dto.AssetId.HasValue) pmSchedule.AssetId = dto.AssetId;
|
||||
if (dto.LocationId.HasValue) pmSchedule.LocationId = dto.LocationId;
|
||||
|
||||
pmSchedule.LastModificationTime = DateTime.UtcNow;
|
||||
if (int.TryParse(userId, out int userIdInt))
|
||||
pmSchedule.LastModifierUserId = userIdInt;
|
||||
|
||||
await _pmScheduleDataService.UpdateAsync(pmSchedule);
|
||||
return MapToDTO(pmSchedule);
|
||||
}
|
||||
|
||||
public async Task DeletePMScheduleAsync(int id, string userId)
|
||||
{
|
||||
var pmSchedule = await _pmScheduleDataService.GetByIdAsync(id);
|
||||
if (pmSchedule == null)
|
||||
throw new InvalidOperationException($"PM Schedule with ID {id} not found");
|
||||
|
||||
pmSchedule.IsDeleted = true;
|
||||
pmSchedule.DeleterUserId = userId;
|
||||
pmSchedule.DeletionTime = DateTime.UtcNow;
|
||||
|
||||
await _pmScheduleDataService.UpdateAsync(pmSchedule);
|
||||
}
|
||||
|
||||
public async Task<bool> PMScheduleExistsAsync(int id)
|
||||
{
|
||||
return await _pmScheduleDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalPMScheduleCountAsync()
|
||||
{
|
||||
return await _pmScheduleDataService.CountAsync();
|
||||
}
|
||||
|
||||
private PMScheduleDTO MapToDTO(PMSchedules pmSchedule)
|
||||
{
|
||||
return new PMScheduleDTO
|
||||
{
|
||||
Id = pmSchedule.Id,
|
||||
Name = pmSchedule.Name,
|
||||
Frequency = pmSchedule.Frequency,
|
||||
StartDate = pmSchedule.StartDate,
|
||||
IsActive = pmSchedule.IsActive,
|
||||
AssetId = pmSchedule.AssetId,
|
||||
AssetName = pmSchedule.Asset?.Name,
|
||||
LocationId = pmSchedule.LocationId,
|
||||
LocationName = pmSchedule.Location?.Name,
|
||||
CreatedDate = pmSchedule.CreatedDate
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
130
SeaHaven.Services/Implementation/VendorService.cs
Normal file
130
SeaHaven.Services/Implementation/VendorService.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
using Data.SeaHavenIndustries;
|
||||
using SeaHaven.DataServices.Interfaces;
|
||||
using SeaHaven.Services.DTOs;
|
||||
using SeaHaven.Services.Interfaces;
|
||||
|
||||
namespace SeaHaven.Services.Implementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Vendor service implementation
|
||||
/// Contains business logic, validation, and orchestration for Vendor operations
|
||||
/// </summary>
|
||||
public class VendorService : IVendorService
|
||||
{
|
||||
private readonly IVendorDataService _vendorDataService;
|
||||
|
||||
public VendorService(IVendorDataService vendorDataService)
|
||||
{
|
||||
_vendorDataService = vendorDataService;
|
||||
}
|
||||
|
||||
public async Task<VendorDTO?> GetVendorByIdAsync(int id)
|
||||
{
|
||||
var vendor = await _vendorDataService.GetByIdAsync(id);
|
||||
return vendor == null ? null : MapToDTO(vendor);
|
||||
}
|
||||
|
||||
public async Task<VendorDTO?> GetVendorByIdWithDetailsAsync(int id)
|
||||
{
|
||||
var vendor = await _vendorDataService.GetByIdWithDetailsAsync(id);
|
||||
return vendor == null ? null : MapToDTO(vendor);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<VendorDTO>> GetAllVendorsAsync()
|
||||
{
|
||||
var vendors = await _vendorDataService.GetAllAsync();
|
||||
return vendors.Select(MapToDTO);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<VendorDTO>> GetVendorsPagedAsync(int page, int pageSize, string? search = null)
|
||||
{
|
||||
var (items, totalCount) = await _vendorDataService.GetPagedAsync(page, pageSize, search);
|
||||
return new PagedResult<VendorDTO>
|
||||
{
|
||||
Items = items.Select(MapToDTO).ToList(),
|
||||
TotalCount = totalCount,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<VendorDTO> CreateVendorAsync(CreateVendorDTO dto, string userId)
|
||||
{
|
||||
var vendor = new Vendor
|
||||
{
|
||||
CompanyName = dto.Name,
|
||||
Email = dto.Email,
|
||||
Phone = dto.Phone,
|
||||
Address = dto.Address,
|
||||
City = dto.City,
|
||||
State = dto.State,
|
||||
Zip = dto.Zipcode,
|
||||
CreatedDate = DateTime.UtcNow,
|
||||
createdby = userId
|
||||
};
|
||||
|
||||
var created = await _vendorDataService.AddAsync(vendor);
|
||||
return MapToDTO(created);
|
||||
}
|
||||
|
||||
public async Task<VendorDTO> UpdateVendorAsync(int id, UpdateVendorDTO dto, string userId)
|
||||
{
|
||||
var vendor = await _vendorDataService.GetByIdAsync(id);
|
||||
if (vendor == null)
|
||||
throw new InvalidOperationException($"Vendor with ID {id} not found");
|
||||
|
||||
if (dto.Name != null) vendor.CompanyName = dto.Name;
|
||||
if (dto.Email != null) vendor.Email = dto.Email;
|
||||
if (dto.Phone != null) vendor.Phone = dto.Phone;
|
||||
if (dto.Address != null) vendor.Address = dto.Address;
|
||||
if (dto.City != null) vendor.City = dto.City;
|
||||
if (dto.State != null) vendor.State = dto.State;
|
||||
if (dto.Zipcode != null) vendor.Zip = dto.Zipcode;
|
||||
|
||||
vendor.LastModificationTime = DateTime.UtcNow;
|
||||
if (int.TryParse(userId, out int userIdInt))
|
||||
vendor.LastModifierUserId = userIdInt;
|
||||
|
||||
await _vendorDataService.UpdateAsync(vendor);
|
||||
return MapToDTO(vendor);
|
||||
}
|
||||
|
||||
public async Task DeleteVendorAsync(int id, string userId)
|
||||
{
|
||||
var vendor = await _vendorDataService.GetByIdAsync(id);
|
||||
if (vendor == null)
|
||||
throw new InvalidOperationException($"Vendor with ID {id} not found");
|
||||
|
||||
vendor.IsDeleted = true;
|
||||
vendor.DeleterUserId = userId;
|
||||
vendor.DeletionTime = DateTime.UtcNow;
|
||||
|
||||
await _vendorDataService.UpdateAsync(vendor);
|
||||
}
|
||||
|
||||
public async Task<bool> VendorExistsAsync(int id)
|
||||
{
|
||||
return await _vendorDataService.ExistsAsync(id);
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalVendorCountAsync()
|
||||
{
|
||||
return await _vendorDataService.CountAsync();
|
||||
}
|
||||
|
||||
private VendorDTO MapToDTO(Vendor vendor)
|
||||
{
|
||||
return new VendorDTO
|
||||
{
|
||||
Id = vendor.Id,
|
||||
Name = vendor.CompanyName,
|
||||
Email = vendor.Email,
|
||||
Phone = vendor.Phone,
|
||||
Address = vendor.Address,
|
||||
City = vendor.City,
|
||||
State = vendor.State,
|
||||
Zipcode = vendor.Zip
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue