using System.Collections.Immutable; using Connected.Caching; using Connected.Entities; using Connected.Entities.Storage; using Connected.Notifications.Events; using Connected.ServiceModel; using Connected.Services; namespace Logistics.Types.WarehouseLocations; internal sealed class WarehouseLocationOps { public sealed class Delete : ServiceAction> { public Delete(IStorageProvider storage, IWarehouseLocationService locations, IEventService events, ICachingService cache) { Storage = storage; Locations = locations; Events = events; Cache = cache; } private IStorageProvider Storage { get; } private IWarehouseLocationService Locations { get; } private IEventService Events { get; } private ICachingService Cache { get; } protected override async Task OnInvoke() { if (await Locations.Select(Arguments.Id) is not IWarehouseLocation entity) return; SetState(entity); await Storage.Open().Update(Arguments.AsEntity(State.Deleted)); } protected override async Task OnCommitted() { await Cache.Remove(WarehouseLocation.EntityKey, Arguments.Id); await Events.Enqueue(this, Events, nameof(IWarehouseLocationService.Deleted), Arguments); } } public sealed class Insert : ServiceFunction { public Insert(IStorageProvider storage, IEventService events) { Storage = storage; Events = events; } private IStorageProvider Storage { get; } private IEventService Events { get; } protected override async Task OnInvoke() { return (await Storage.Open().Update(Arguments.AsEntity(State.New))).Id; } protected override async Task OnCommitted() { await Events.Enqueue(this, Events, nameof(IWarehouseLocationService.Inserted), Arguments); } } public sealed class Query : ServiceFunction> { public Query(IWarehouseLocationCache locations) { Locations = locations; } public IWarehouseLocationCache Locations { get; } protected override async Task> OnInvoke() { return await (from e in Locations select e).WithArguments(Arguments).AsEntities(); } } public sealed class QueryByWarehouse : ServiceFunction> { public QueryByWarehouse(IWarehouseLocationCache locations) { Locations = locations; } public IWarehouseLocationCache Locations { get; } protected override async Task> OnInvoke() { return await (from e in Locations where e.Warehouse == Arguments.Warehouse select e).WithArguments(Arguments).AsEntities(); } } public sealed class QueryChildren : ServiceFunction> { public QueryChildren(IWarehouseLocationCache locations) { Locations = locations; } public IWarehouseLocationCache Locations { get; } protected override async Task> OnInvoke() { return await (from e in Locations where e.Warehouse == Arguments.Warehouse && (Arguments.Parent is null || e.Parent == Arguments.Parent) select e).WithArguments(Arguments).AsEntities(); } } public sealed class Lookup : ServiceFunction, ImmutableList> { public Lookup(IWarehouseLocationCache locations) { Locations = locations; } public IWarehouseLocationCache Locations { get; } protected override async Task> OnInvoke() { return await (from e in Locations where Arguments.IdList.Any(f => f == e.Id) select e).AsEntities(); } } public sealed class Select : NullableServiceFunction, IWarehouseLocation> { public Select(IWarehouseLocationCache locations) { Locations = locations; } private IWarehouseLocationCache Locations { get; } protected override async Task OnInvoke() { return await (from e in Locations where e.Id == Arguments.Id select e).AsEntity(); } } public sealed class SelectByCode : NullableServiceFunction { public SelectByCode(IWarehouseLocationCache locations) { Locations = locations; } private IWarehouseLocationCache Locations { get; } protected override async Task OnInvoke() { return await (from e in Locations where string.Equals(e.Code, Arguments.Code, StringComparison.OrdinalIgnoreCase) select e).AsEntity(); } } public sealed class Update : ServiceAction { public Update(IStorageProvider storage, IWarehouseLocationCache cache, IWarehouseLocationService locations, IEventService events) { Storage = storage; Cache = cache; Locations = locations; Events = events; } private IStorageProvider Storage { get; } private IWarehouseLocationCache Cache { get; } private IWarehouseLocationService Locations { get; } private IEventService Events { get; } protected override async Task OnInvoke() { if (SetState(await Locations.Select(Arguments.Id)) is not WarehouseLocation entity) return; await Storage.Open().Update(entity.Merge(Arguments, State.Default), Arguments, async () => { await Cache.Refresh(Arguments.Id); return SetState(await Locations.Select(Arguments.Id)) as WarehouseLocation; }); } protected override async Task OnCommitted() { await Cache.Refresh(Arguments.Id); await Events.Enqueue(this, Locations, nameof(Locations.Updated), Arguments); } } }