//public override string FeedPath { get; protected set; } = "example path override"; protected override async Task <List <RpdeItem> > GetRPDEItems(string clientId, long?afterTimestamp, string afterId) { using (var db = FakeBookingSystem.Database.Mem.Database.Open()) { long afterTimestampLong = afterTimestamp ?? 0; var q = db.From <OrderTable>() .LeftJoin <OrderTable, OrderItemsTable>((orders, items) => orders.OrderId == items.OrderId) .OrderBy(x => x.OrderProposalModified) .ThenBy(x => x.OrderId) .Where(x => x.VisibleInOrderProposalsFeed != FeedVisibility.None && x.ClientId == clientId && ( x.OrderProposalModified > afterTimestampLong || (x.OrderProposalModified == afterTimestamp && // Note this comparison will fail OpenActive validation if using SQL Server GUIDs due to the SQL Server GUID ordering // Use SQL Server rowversion and OrdersRPDEFeedIncrementingUniqueChangeNumber instead string.Compare(afterId, x.OrderId, StringComparison.InvariantCulture) > 0)) && x.OrderProposalModified < (DateTimeOffset.UtcNow - new TimeSpan(0, 0, 2)).UtcTicks) .Take(RPDEPageSize); var query = db .SelectMulti <OrderTable, OrderItemsTable>(q) .GroupBy(x => new { x.Item1.OrderId }) .Select(result => new { OrderTable = result.Select(item => new { item.Item1 }).FirstOrDefault()?.Item1, OrderItemsTable = result.Select(item => new { item.Item2 }).ToList().Select(orderItem => orderItem.Item2).ToList() }) .Select(result => new RpdeItem { Kind = RpdeKind.Order, Id = result.OrderTable.OrderId, Modified = result.OrderTable.OrderProposalModified, State = result.OrderTable.Deleted || result.OrderTable.VisibleInOrderProposalsFeed == FeedVisibility.Archived ? RpdeState.Deleted : RpdeState.Updated, Data = result.OrderTable.Deleted || result.OrderTable.VisibleInOrderProposalsFeed == FeedVisibility.Archived ? null : AcmeOrderStore.RenderOrderFromDatabaseResult(RenderOrderId(result.OrderTable.OrderMode == OrderMode.Proposal ? OrderType.OrderProposal : OrderType.Order, new Guid(result.OrderTable.OrderId)), result.OrderTable, result.OrderItemsTable.Select(orderItem => new OrderItem { Id = RenderOrderItemId(OrderType.Order, new Guid(result.OrderTable.OrderId), orderItem.Id), AcceptedOffer = new Offer { Id = orderItem.OfferJsonLdId, Price = orderItem.Price, PriceCurrency = "GBP" }, OrderedItem = orderItem.OpportunityJsonLdId }).ToList() ) }); return(query.ToList()); } }
//public override string FeedPath { get; protected set; } = "example path override"; protected override async Task <List <RpdeItem> > GetRPDEItems(string clientId, long?afterTimestamp, string afterId) { // Note if using SQL Server it is best to use rowversion as the modified value for the Orders table, // and update this class to inherit from OrdersRPDEFeedIncrementingUniqueChangeNumber // (to use afterChangeNumber, instead of afterTimestamp and afterId) using (var db = FakeBookingSystem.Database.Mem.Database.Open()) { long afterTimestampLong = afterTimestamp ?? 0; var q = db.From <OrderTable>() .LeftJoin <OrderTable, OrderItemsTable>((orders, items) => orders.OrderId == items.OrderId) .OrderBy(x => x.OrderModified) .ThenBy(x => x.OrderId) .Where(x => x.VisibleInOrdersFeed != FeedVisibility.None && x.ClientId == clientId && ( x.OrderModified > afterTimestampLong || (x.OrderModified == afterTimestamp && // Note this comparison will fail OpenActive validation if using SQL Server GUIDs due to the SQL Server GUID ordering // Use SQL Server rowversion and OrdersRPDEFeedIncrementingUniqueChangeNumber instead string.Compare(afterId, x.OrderId, StringComparison.InvariantCulture) > 0)) && x.OrderModified < (DateTimeOffset.UtcNow - new TimeSpan(0, 0, 2)).UtcTicks) .Take(RPDEPageSize); var query = db .SelectMulti <OrderTable, OrderItemsTable>(q) .GroupBy(x => new { x.Item1.OrderId }) .Select(result => new { OrderTable = result.Select(item => new { item.Item1 }).FirstOrDefault()?.Item1, OrderItemsTable = result.Select(item => new { item.Item2 }).ToList().Select(orderItem => orderItem.Item2).ToList() }) .Select(result => new RpdeItem { Kind = RpdeKind.Order, Id = result.OrderTable.OrderId, Modified = result.OrderTable.OrderModified, State = result.OrderTable.Deleted || result.OrderTable.VisibleInOrdersFeed == FeedVisibility.Archived ? RpdeState.Deleted : RpdeState.Updated, Data = result.OrderTable.Deleted || result.OrderTable.VisibleInOrdersFeed == FeedVisibility.Archived ? null : AcmeOrderStore.RenderOrderFromDatabaseResult(RenderOrderId(result.OrderTable.OrderMode == OrderMode.Proposal ? OrderType.OrderProposal : OrderType.Order, new Guid(result.OrderTable.OrderId)), result.OrderTable, result.OrderItemsTable.Select(orderItem => new OrderItem { Id = RenderOrderItemId(OrderType.Order, new Guid(result.OrderTable.OrderId), orderItem.Id), AcceptedOffer = new Offer { Id = orderItem.OfferJsonLdId, Price = orderItem.Price, PriceCurrency = "GBP" }, OrderedItem = orderItem.OpportunityJsonLdId, AccessChannel = orderItem.MeetingUrl != null ? new VirtualLocation() { Name = "Zoom Video Chat", Url = orderItem.MeetingUrl, AccessId = orderItem.MeetingId, AccessCode = orderItem.MeetingPassword, Description = "Please log into Zoom a few minutes before the event" } : null, AccessCode = orderItem.PinCode != null ? new List <PropertyValue> { new PropertyValue() { Name = "Pin Code", Description = orderItem.PinCode, Value = "defaultValue" } } : null, AccessPass = orderItem.BarCodeText != null ? new List <ImageObject> { new Barcode() { Url = new Uri(orderItem.ImageUrl), Text = orderItem.BarCodeText, CodeType = "code128" } } : null, OrderItemStatus = orderItem.Status == BookingStatus.Confirmed ? OrderItemStatus.OrderItemConfirmed : orderItem.Status == BookingStatus.CustomerCancelled ? OrderItemStatus.CustomerCancelled : orderItem.Status == BookingStatus.SellerCancelled ? OrderItemStatus.SellerCancelled : orderItem.Status == BookingStatus.Attended ? OrderItemStatus.AttendeeAttended : orderItem.Status == BookingStatus.Absent ? OrderItemStatus.AttendeeAbsent : (OrderItemStatus?)null, CancellationMessage = orderItem.CancellationMessage, CustomerNotice = orderItem.CustomerNotice, }).ToList() ) }); return(query.ToList()); } }