mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 13:03:12 +00:00
Reject soft-deleted accounts and stop account-scoped callers from assigning or stealing locations across tenants.
129 lines
4 KiB
C#
129 lines
4 KiB
C#
using Data.SeaHavenIndustries;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using SeaHaven.DataServices.Interfaces;
|
|
|
|
namespace SeaHaven.DataServices.Implementation
|
|
{
|
|
public class AccountDataService : IAccountDataService
|
|
{
|
|
private readonly ApplicationDbContext _context;
|
|
|
|
public AccountDataService(ApplicationDbContext context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public async Task<Accounts?> GetByIdAsync(int id)
|
|
{
|
|
return await _context.Accounts.FindAsync(id);
|
|
}
|
|
|
|
public async Task<Accounts?> GetByIdWithDetailsAsync(int id)
|
|
{
|
|
return await _context.Accounts
|
|
.Include(a => a.Contacts)
|
|
.Include(a => a.Addresses)
|
|
.FirstOrDefaultAsync(a => a.Id == id);
|
|
}
|
|
|
|
public async Task<IEnumerable<Accounts>> GetAllAsync()
|
|
{
|
|
return await _context.Accounts.ToListAsync();
|
|
}
|
|
|
|
public async Task<(IEnumerable<Accounts> Items, int TotalCount)> GetPagedAsync(
|
|
int page,
|
|
int pageSize,
|
|
string? search = null)
|
|
{
|
|
search ??= "";
|
|
|
|
var query = _context.Accounts
|
|
.Where(a => a.IsDeleted == false || a.IsDeleted == null);
|
|
|
|
if (!string.IsNullOrWhiteSpace(search))
|
|
{
|
|
var s = search.ToLower();
|
|
query = query.Where(a =>
|
|
(a.Name ?? "").ToLower().Contains(s) ||
|
|
(a.Email ?? "").ToLower().Contains(s) ||
|
|
(a.Phone ?? "").Contains(s) ||
|
|
(a.Website ?? "").ToLower().Contains(s)
|
|
);
|
|
}
|
|
|
|
var totalCount = await query.CountAsync();
|
|
var items = await query
|
|
.OrderByDescending(a => a.Id)
|
|
.Skip((page - 1) * pageSize)
|
|
.Take(pageSize)
|
|
.ToListAsync();
|
|
|
|
return (items, totalCount);
|
|
}
|
|
|
|
public async Task<Accounts> AddAsync(Accounts account)
|
|
{
|
|
account.CreatedDate = DateTime.Now;
|
|
await _context.Accounts.AddAsync(account);
|
|
await _context.SaveChangesAsync();
|
|
return account;
|
|
}
|
|
|
|
public async Task UpdateAsync(Accounts account)
|
|
{
|
|
account.LastModificationTime = DateTime.Now;
|
|
_context.Accounts.Update(account);
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
|
|
public async Task DeleteAsync(int id)
|
|
{
|
|
var entity = await GetByIdAsync(id);
|
|
if (entity != null)
|
|
{
|
|
_context.Accounts.Remove(entity);
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
}
|
|
|
|
public async Task<bool> ExistsAsync(int id)
|
|
{
|
|
return await _context.Accounts.AnyAsync(a => a.Id == id);
|
|
}
|
|
|
|
public async Task<bool> ExistsActiveAsync(int id, CancellationToken cancellationToken = default)
|
|
{
|
|
return await _context.Accounts
|
|
.AsNoTracking()
|
|
.AnyAsync(
|
|
a => a.Id == id && (a.IsDeleted == false || a.IsDeleted == null),
|
|
cancellationToken);
|
|
}
|
|
|
|
public async Task<int> CountAsync()
|
|
{
|
|
return await _context.Accounts.CountAsync();
|
|
}
|
|
|
|
public async Task<int?> TryGetUniqueActiveIdByExactNameAsync(
|
|
string? name,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(name))
|
|
return null;
|
|
|
|
var trimmed = name.Trim();
|
|
var matches = await _context.Accounts
|
|
.AsNoTracking()
|
|
.Where(a =>
|
|
a.Name == trimmed
|
|
&& (a.IsDeleted == false || a.IsDeleted == null))
|
|
.Select(a => a.Id)
|
|
.Take(2)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
return matches.Count == 1 ? matches[0] : null;
|
|
}
|
|
}
|
|
}
|