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.Documents.Receive; internal sealed class ReceiveDocumentOps { public sealed class Delete : ServiceAction> { public Delete(IReceiveDocumentService documents, IStorageProvider storage, ICacheContext cache, IEventService events) { Documents = documents; Storage = storage; Cache = cache; Events = events; } private IReceiveDocumentService Documents { get; } private IStorageProvider Storage { get; } private ICacheContext Cache { get; } private IEventService Events { get; } protected override async Task OnInvoke() { if (SetState(await Documents.Select(Arguments)) is not IReceiveDocument document) return; /* * Delete all items */ foreach (var item in await Documents.QueryItems(document.Id)) await Documents.DeleteItem(item.Id); /* * Delete document */ await Storage.Open().Update(Arguments.AsEntity(State.Deleted)); } protected override async Task OnCommitted() { await Cache.Remove(ReceiveDocument.EntityKey, Arguments.Id); await Events.Enqueue(this, Documents, nameof(IReceiveDocumentService.Deleted), Arguments); } } public sealed class Insert : ServiceFunction { public Insert(IStorageProvider storage, IEventService events, IReceiveDocumentService documents) { Storage = storage; Events = events; Documents = documents; } private IStorageProvider Storage { get; } private IEventService Events { get; } private IReceiveDocumentService Documents { 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, Documents, nameof(IReceiveDocumentService.Inserted), new PrimaryKeyArgs { Id = Result }); } } public sealed class Query : ServiceFunction> { public Query(IStorageProvider storage) { Storage = storage; } public IStorageProvider Storage { get; } protected override async Task> OnInvoke() { return await (from e in Storage.Open() select e).WithArguments(Arguments).AsEntities(); } } public sealed class Select : NullableServiceFunction, IReceiveDocument?> { public Select(IStorageProvider storage, ICacheContext cache) { Storage = storage; Cache = cache; } private IStorageProvider Storage { get; } private ICacheContext Cache { get; } protected override async Task OnInvoke() { return await Cache.Get(ReceiveDocument.EntityKey, Arguments.Id, async (f) => { return await (from e in Storage.Open() where e.Id == Arguments.Id select e).AsEntity(); }); } } public sealed class Update : ServiceAction { public Update(IStorageProvider storage, ICacheContext cache, IEventService events, IReceiveDocumentService documents) { Storage = storage; Cache = cache; Events = events; Documents = documents; } private IStorageProvider Storage { get; } private ICacheContext Cache { get; } private IEventService Events { get; } private IReceiveDocumentService Documents { get; } protected override async Task OnInvoke() { if (await Documents.Select(Arguments.Id) is not ReceiveDocument entity) return; await Storage.Open().Update(entity, Arguments, async () => { await Cache.Remove(ReceiveDocument.EntityKey, Arguments.Id); return (await Documents.Select(Arguments.Id)) as ReceiveDocument; }); } protected override async Task OnCommitted() { await Cache.Remove(ReceiveDocument.EntityKey, Arguments.Id); await Events.Enqueue(this, Documents, nameof(IReceiveDocumentService.Updated), Arguments); } } }