135 lines
4.5 KiB
C#
135 lines
4.5 KiB
C#
using Distribution.Infra.Authorization;
|
|
using Distribution.Infra.UoW;
|
|
|
|
namespace Distribution.Features.Order;
|
|
|
|
public class OrderService(IOrderRepository repo, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess)
|
|
{
|
|
private const int GlobalScopeRoleLevel = 50;
|
|
|
|
private static OrderResponse ToResponse(Models.Order o, List<Models.OrderItem> items) =>
|
|
new(o.Id, o.OrderDate, o.FK_StoreId, o.TotalAmount,
|
|
items.Select(i => new OrderItemResponse(i.FK_ItemId, i.Quantity)).ToList(),
|
|
o.IsActive, o.CreatedAt);
|
|
|
|
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<OrderResponse>> GetAllAsync()
|
|
{
|
|
var orders = (await repo.GetAllAsync()).Where(o => o.IsActive).ToList();
|
|
if (!HasGlobalScope && currentUser.UserId is not null)
|
|
{
|
|
var accessibleStoreIds = (await scopeAccess.GetAccessibleStoreIdsAsync(currentUser.UserId.Value)).ToHashSet();
|
|
orders = orders.Where(o => accessibleStoreIds.Contains(o.FK_StoreId)).ToList();
|
|
}
|
|
var result = new List<OrderResponse>();
|
|
foreach (var order in orders)
|
|
{
|
|
var items = await repo.GetItemsByOrderIdAsync(order.Id);
|
|
result.Add(ToResponse(order, items));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public async Task<OrderResponse?> GetByIdAsync(Guid id)
|
|
{
|
|
var order = await repo.GetByIdAsync(id);
|
|
if (order is null || !order.IsActive) return null;
|
|
if (!await HasStoreScopeAsync(order.FK_StoreId)) return null;
|
|
var items = await repo.GetItemsByOrderIdAsync(id);
|
|
return ToResponse(order, items);
|
|
}
|
|
|
|
public async Task<List<OrderResponse>?> GetByStoreIdAsync(Guid storeId)
|
|
{
|
|
if (!await HasStoreScopeAsync(storeId)) return null;
|
|
var orders = await repo.GetByStoreIdAsync(storeId);
|
|
var result = new List<OrderResponse>();
|
|
foreach (var order in orders)
|
|
{
|
|
var items = await repo.GetItemsByOrderIdAsync(order.Id);
|
|
result.Add(ToResponse(order, items));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public async Task<OrderResponse?> CreateAsync(CreateOrderRequest request, CancellationToken ct = default)
|
|
{
|
|
if (!await HasStoreScopeAsync(request.StoreId)) return null;
|
|
|
|
var order = new Models.Order
|
|
{
|
|
FK_StoreId = request.StoreId,
|
|
OrderDate = request.OrderDate,
|
|
TotalAmount = request.TotalAmount
|
|
};
|
|
var orderItems = request.Items.Select(i => new Models.OrderItem
|
|
{
|
|
FK_OrderId = order.Id,
|
|
FK_ItemId = i.ItemId,
|
|
Quantity = i.Quantity
|
|
}).ToList();
|
|
|
|
await uow.BeginAsync(ct);
|
|
try
|
|
{
|
|
await repo.AddAsync(order);
|
|
await repo.AddItemsAsync(orderItems);
|
|
await uow.CommitAsync(ct);
|
|
}
|
|
catch
|
|
{
|
|
await uow.RollbackAsync(ct);
|
|
throw;
|
|
}
|
|
return ToResponse(order, orderItems);
|
|
}
|
|
|
|
public async Task<OrderResponse?> UpdateAsync(Guid id, UpdateOrderRequest request, CancellationToken ct = default)
|
|
{
|
|
var order = await repo.GetByIdAsync(id);
|
|
if (order is null || !order.IsActive) return null;
|
|
if (!await HasStoreScopeAsync(order.FK_StoreId)) return null;
|
|
order.OrderDate = request.OrderDate;
|
|
order.TotalAmount = request.TotalAmount;
|
|
await uow.BeginAsync(ct);
|
|
try
|
|
{
|
|
repo.Update(order);
|
|
await uow.CommitAsync(ct);
|
|
}
|
|
catch
|
|
{
|
|
await uow.RollbackAsync(ct);
|
|
throw;
|
|
}
|
|
var items = await repo.GetItemsByOrderIdAsync(id);
|
|
return ToResponse(order, items);
|
|
}
|
|
|
|
public async Task<bool> DeleteAsync(Guid id, CancellationToken ct = default)
|
|
{
|
|
var order = await repo.GetByIdAsync(id);
|
|
if (order is null || !order.IsActive) return false;
|
|
if (!await HasStoreScopeAsync(order.FK_StoreId)) return false;
|
|
await uow.BeginAsync(ct);
|
|
try
|
|
{
|
|
repo.Remove(order);
|
|
await uow.CommitAsync(ct);
|
|
}
|
|
catch
|
|
{
|
|
await uow.RollbackAsync(ct);
|
|
throw;
|
|
}
|
|
return true;
|
|
}
|
|
}
|