using System.Collections.Immutable; using Connected.Caching; using Connected.Entities; using Connected.Entities.Storage; using Connected.Interop; using Connected.Notifications.Events; using Connected.ServiceModel; using Connected.Services; namespace Logistics.Documents.Receive; internal sealed class ReceivePlannedItemsOps { public sealed class Query : ServiceFunction, ImmutableList> { public Query(IStorageProvider storage) { Storage = storage; } private IStorageProvider Storage { get; } protected override async Task> OnInvoke() { return await (from e in Storage.Open() where e.Document == Arguments.Id select e).AsEntities(); } } public sealed class QueryByItem : ServiceFunction, ImmutableList> { public QueryByItem(IStorageProvider storage) { Storage = storage; } private IStorageProvider Storage { get; } protected override async Task> OnInvoke() { return await (from e in Storage.Open() where e.Item == Arguments.Id select e).AsEntities(); } } public sealed class Select : NullableServiceFunction, IReceivePlannedItem> { 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(ReceivePlannedItem.EntityKey, Arguments.Id, async (f) => { return await (from e in Storage.Open() where e.Id == Arguments.Id select e).AsEntity(); }); } } public sealed class SelectByEntity : NullableServiceFunction { public SelectByEntity(IStorageProvider storage, ICacheContext cache, IReceiveDocumentService documents, IReceivePostingDocumentService postingDocuments) { Storage = storage; Cache = cache; Documents = documents; PostingDocuments = postingDocuments; } private IStorageProvider Storage { get; } private ICacheContext Cache { get; } private IReceiveDocumentService Documents { get; } private IReceivePostingDocumentService PostingDocuments { get; } protected override async Task OnInvoke() { if (await PostingDocuments.Select(Arguments.Document) is not IReceivePostingDocument postingDocument) return null; if (await Documents.SelectItem(Arguments.AsArguments(new { postingDocument.Document })) is not IReceiveItem item) return null; return await Cache.Get(ReceivePlannedItem.EntityKey, f => f.Item == item.Id, async (f) => { return await (from e in Storage.Open() where e.Item == item.Id select e).AsEntity(); }); } } public sealed class Update : ServiceAction { public Update(IStorageProvider storage, ICacheContext cache, IEventService events, IReceivePostingDocumentService documents) { Storage = storage; Cache = cache; Events = events; Documents = documents; } private IStorageProvider Storage { get; } private ICacheContext Cache { get; } private IEventService Events { get; } private IReceivePostingDocumentService Documents { get; } protected override async Task OnInvoke() { if (await Documents.SelectPlannedItem(Arguments.Id) is not ReceivePlannedItem entity) return; await Storage.Open().Update(entity, Arguments, async () => { await Cache.Remove(ReceivePlannedItem.EntityKey, Arguments.Id); return (await Documents.SelectPlannedItem(Arguments.Id)) as ReceivePlannedItem; }); await Cache.Remove(ReceivePlannedItem.EntityKey, Arguments.Id); } protected override async Task OnCommitted() { await Events.Enqueue(this, Documents, nameof(IReceivePostingDocumentService.PlannedItemUpdated), Arguments); } } }