using Connected.Entities; using Connected.Logistics.Types.Warehouses; using Connected.Middleware; using Connected.Validation; namespace Connected.Logistics.Types.WarehouseLocations; internal sealed class InsertWarehouseLocationValidation : MiddlewareComponent, IValidator { public InsertWarehouseLocationValidation(IWarehouseLocationCache cache, IWarehouseService warehouses) { Cache = cache; Warehouses = warehouses; } private IWarehouseLocationCache Cache { get; } private IWarehouseService Warehouses { get; } public async Task Validate(InsertWarehouseLocationArgs args) { /* * Warehouse existence */ if (await Warehouses.Select(args.Warehouse) is null) throw ValidationExceptions.NotFound(nameof(args.Warehouse), args.Warehouse); /* * Code is unique */ if (await (from e in Cache where string.Equals(e.Code, args.Code, StringComparison.OrdinalIgnoreCase) select e).AsEntity() is not null) throw ValidationExceptions.ValueExists(nameof(args.Code), args.Code); /* * Check parent */ if (args.Parent is not null) { var parent = await (from e in Cache where e.Id == args.Parent select e).AsEntity(); if (parent is null) throw ValidationExceptions.NotFound(nameof(args.Parent), args.Parent); /* * Parent and entity must be in the same warehouse. */ if (parent.Warehouse != args.Warehouse) throw ValidationExceptions.Mismatch(nameof(args.Warehouse), args.Warehouse); } } } internal sealed class UpdateWarehouseLocationValidation : MiddlewareComponent, IValidator { public UpdateWarehouseLocationValidation(IWarehouseLocationCache cache) { Cache = cache; } private IWarehouseLocationCache Cache { get; } public async Task Validate(UpdateWarehouseLocationArgs args) { if (await (from e in Cache where e.Id == args.Id select e).AsEntity() is not WarehouseLocation entity) return; /* * Code is unique */ if (await (from e in Cache where string.Equals(e.Code, args.Code, StringComparison.OrdinalIgnoreCase) && e.Id != args.Id select e).AsEntity() is not null) throw ValidationExceptions.ValueExists(nameof(args.Code), args.Code); /* * Check parent */ if (args.Parent is not null) { var parent = await (from e in Cache where e.Id == args.Parent select e).AsEntity(); if (parent is null) throw ValidationExceptions.NotFound(nameof(args.Parent), args.Parent); /* * Parent and entity must be in the same warehouse. */ if (parent.Warehouse != entity.Warehouse) throw ValidationExceptions.Mismatch(nameof(args.Parent), args.Parent); /* * nesting under self */ if (parent.Id == args.Id) throw ValidationExceptions.Mismatch(nameof(args.Parent), args.Parent); var currentParent = await (from e in Cache where e.Id == parent.Parent select e).AsEntity(); while (currentParent is not null) { if (currentParent.Id == args.Id) throw ValidationExceptions.Mismatch(nameof(args.Parent), args.Parent); currentParent = await (from e in Cache where e.Id == currentParent.Parent select e).AsEntity(); } } } }