110 lines
4.3 KiB
C#
110 lines
4.3 KiB
C#
using Distribution.Infra.Auth;
|
|
using Distribution.Infra.UoW;
|
|
|
|
namespace Distribution.Features.Store;
|
|
|
|
public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess)
|
|
{
|
|
private const int GlobalScopeRoleLevel = 50;
|
|
|
|
private bool HasGlobalScope => currentUser.RoleLevel >= GlobalScopeRoleLevel;
|
|
|
|
private async Task<bool> HasStoreScopeAsync(Guid storeId)
|
|
{
|
|
if (HasGlobalScope || currentUser.UserId is null) return HasGlobalScope;
|
|
return await scopeAccess.HasStoreScopeAsync(currentUser.UserId.Value, storeId);
|
|
}
|
|
|
|
public async Task<List<StoreResponse>> GetAllAsync()
|
|
{
|
|
var stores = (await repo.GetAllAsync()).Where(s => s.IsActive).ToList();
|
|
if (!HasGlobalScope && currentUser.UserId is not null)
|
|
{
|
|
var accessibleStoreIds = (await scopeAccess.GetAccessibleStoreIdsAsync(currentUser.UserId.Value)).ToHashSet();
|
|
stores = stores.Where(s => accessibleStoreIds.Contains(s.Id)).ToList();
|
|
}
|
|
return stores.Select(s => new StoreResponse(s.Id, s.FK_RouteId, s.OwnerName, s.StoreName, s.StoreAddress, s.Latitude, s.Longitude, s.OneTimeAmount, s.CreditAmount, s.IsActive, s.CreatedAt)).ToList();
|
|
}
|
|
|
|
public async Task<StoreResponse?> GetByIdAsync(Guid id)
|
|
{
|
|
var store = await repo.GetByIdAsync(id);
|
|
if (store is null || !store.IsActive) return null;
|
|
if (!await HasStoreScopeAsync(id)) return null;
|
|
return new StoreResponse(store.Id, store.FK_RouteId, store.OwnerName, store.StoreName, store.StoreAddress, store.Latitude, store.Longitude, store.OneTimeAmount, store.CreditAmount, store.IsActive, store.CreatedAt);
|
|
}
|
|
|
|
public async Task<StoreResponse> CreateAsync(CreateStoreRequest request, CancellationToken ct = default)
|
|
{
|
|
var store = new Models.Store
|
|
{
|
|
FK_RouteId = request.RouteId,
|
|
OwnerName = request.OwnerName,
|
|
StoreName = request.StoreName,
|
|
StoreAddress = request.StoreAddress,
|
|
Latitude = request.Latitude,
|
|
Longitude = request.Longitude,
|
|
OneTimeAmount = request.OneTimeAmount,
|
|
CreditAmount = request.CreditAmount
|
|
};
|
|
await uow.BeginAsync(ct);
|
|
try
|
|
{
|
|
await repo.AddAsync(store);
|
|
await uow.CommitAsync(ct);
|
|
}
|
|
catch
|
|
{
|
|
await uow.RollbackAsync(ct);
|
|
throw;
|
|
}
|
|
return new StoreResponse(store.Id, store.FK_RouteId, store.OwnerName, store.StoreName, store.StoreAddress, store.Latitude, store.Longitude, store.OneTimeAmount, store.CreditAmount, store.IsActive, store.CreatedAt);
|
|
}
|
|
|
|
public async Task<StoreResponse?> UpdateAsync(Guid id, UpdateStoreRequest request, CancellationToken ct = default)
|
|
{
|
|
var store = await repo.GetByIdAsync(id);
|
|
if (store is null || !store.IsActive) return null;
|
|
if (!await HasStoreScopeAsync(id)) return null;
|
|
store.FK_RouteId = request.RouteId;
|
|
store.OwnerName = request.OwnerName;
|
|
store.StoreName = request.StoreName;
|
|
store.StoreAddress = request.StoreAddress;
|
|
store.Latitude = request.Latitude;
|
|
store.Longitude = request.Longitude;
|
|
store.OneTimeAmount = request.OneTimeAmount;
|
|
store.CreditAmount = request.CreditAmount;
|
|
await uow.BeginAsync(ct);
|
|
try
|
|
{
|
|
repo.Update(store);
|
|
await uow.CommitAsync(ct);
|
|
}
|
|
catch
|
|
{
|
|
await uow.RollbackAsync(ct);
|
|
throw;
|
|
}
|
|
return new StoreResponse(store.Id, store.FK_RouteId, store.OwnerName, store.StoreName, store.StoreAddress, store.Latitude, store.Longitude, store.OneTimeAmount, store.CreditAmount, store.IsActive, store.CreatedAt);
|
|
}
|
|
|
|
public async Task<bool> DeleteAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
var store = await repo.GetByIdAsync(id);
|
|
if (store is null || !store.IsActive) return false;
|
|
if (!await HasStoreScopeAsync(id)) return false;
|
|
await uow.BeginAsync(ct);
|
|
try
|
|
{
|
|
repo.Remove(store);
|
|
await uow.CommitAsync(ct);
|
|
}
|
|
catch
|
|
{
|
|
await uow.RollbackAsync(ct);
|
|
throw;
|
|
}
|
|
return true;
|
|
}
|
|
}
|