Skip to content

Commit 821e182

Browse files
civsivlukehesluke
andauthored
feat: elaborate TODOs (#227)
* feat: elaborate TODOs * Feature/remove remainingattendeecapacity from b (#229) * feat: remove remainingAttendeeCapacity and maximumAttendeeCapacity from B response * remove from P response too * Update OpenActive.Server.NET/CustomBookingEngine/CustomBookingEngine.cs Co-authored-by: Luke Winship <luke.winship@gmail.com> * elaborate a todo --------- Co-authored-by: Luke Winship <luke.winship@gmail.com>
1 parent 1424341 commit 821e182

11 files changed

Lines changed: 48 additions & 25 deletions

File tree

Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Users/UserRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public async Task<User> FindByUsername(string username)
3333
return GetUserFromSellerUser(await _fakeBookingSystem.Database.GetSellerUser(username));
3434
}
3535

36-
// TODO: Make this an extension method
36+
// TODO: Make this an extension method to Claim class
3737
private static void AddClaimIfNotNull(List<Claim> claims, string key, string value)
3838
{
3939
if (!string.IsNullOrEmpty(value))

Examples/BookingSystem.AspNetCore/Extensions/BookedOrderItemHelper.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,13 @@ public static void AddPropertiesToBookedOrderItem(IOrderItemContext ctx, BookedO
5252
}
5353
}
5454

55+
public static void RemovePropertiesFromBookedOrderItem(IOrderItemContext ctx)
56+
{
57+
// Set RemainingAttendeeCapacity and MaximumAttendeeCapacity to null as the do not belong in the B and P responses.
58+
// For more information see: https://github.com/openactive/open-booking-api/issues/156#issuecomment-926643733
59+
ctx.ResponseOrderItem.OrderedItem.Object.RemainingAttendeeCapacity = null;
60+
ctx.ResponseOrderItem.OrderedItem.Object.MaximumAttendeeCapacity = null;
61+
}
62+
5563
}
5664
}

Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ protected override async Task GetOrderItems(List<OrderItemContext<FacilityOpport
358358
OrderItem = new OrderItem
359359
{
360360
// TODO: The static example below should come from the database (which doesn't currently support tax)
361+
// This is because it can be different for each Seller and needs to calculated at the time of booking
361362
UnitTaxSpecification = GetUnitTaxSpecification(flowContext, slot),
362363
AcceptedOffer = new Offer
363364
{
@@ -512,7 +513,8 @@ protected override async ValueTask LeaseOrderItems(Lease lease, List<OrderItemCo
512513
}
513514
}
514515

515-
//TODO: This should reuse code of LeaseOrderItem
516+
// TODO: This should reuse code of LeaseOrderItem to be DRY. Similar logic is also used in ProposeOrderItems as well as
517+
// in LeaseOrderItems, BookOrderItems, and ProposeOrderItems in the FacilityStore. The issue for this is: https://github.com/openactive/OpenActive.Server.NET/issues/226
516518
protected override async ValueTask BookOrderItems(List<OrderItemContext<FacilityOpportunity>> orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction)
517519
{
518520
// Check that there are no conflicts between the supplied opportunities
@@ -558,6 +560,8 @@ protected override async ValueTask BookOrderItems(List<OrderItemContext<Facility
558560
// Set OrderItemId and access properties for each orderItemContext
559561
ctx.SetOrderItemId(flowContext, bookedOrderItemInfo.OrderItemId);
560562
BookedOrderItemHelper.AddPropertiesToBookedOrderItem(ctx, bookedOrderItemInfo);
563+
// Remove attendee capacity information from the OrderedItem. For more information see: https://github.com/openactive/open-booking-api/issues/156#issuecomment-926643733
564+
BookedOrderItemHelper.RemovePropertiesFromBookedOrderItem(ctx);
561565
}
562566
break;
563567
case ReserveOrderItemsResult.SellerIdMismatch:
@@ -574,7 +578,7 @@ protected override async ValueTask BookOrderItems(List<OrderItemContext<Facility
574578
}
575579
}
576580

577-
// TODO check logic here, it's just been copied from BookOrderItems. Possibly could remove duplication here.
581+
// TODO check logic here, it's just been copied from BookOrderItems. Possibly could remove duplication here. Common logic between this, BookOrderItems, and LeaseOrderItems should be pulled out.
578582
protected override async ValueTask ProposeOrderItems(List<OrderItemContext<FacilityOpportunity>> orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction)
579583
{
580584
// Check that there are no conflicts between the supplied opportunities
@@ -619,6 +623,8 @@ protected override async ValueTask ProposeOrderItems(List<OrderItemContext<Facil
619623
foreach (var (ctx, bookedOrderItemInfo) in ctxGroup.Zip(bookedOrderItemInfos, (ctx, bookedOrderItemInfo) => (ctx, bookedOrderItemInfo)))
620624
{
621625
ctx.SetOrderItemId(flowContext, bookedOrderItemInfo.OrderItemId);
626+
// Remove attendee capacity information from the OrderedItem. For more information see: https://github.com/openactive/open-booking-api/issues/156#issuecomment-926643733
627+
BookedOrderItemHelper.RemovePropertiesFromBookedOrderItem(ctx);
622628
}
623629
break;
624630
case ReserveOrderItemsResult.SellerIdMismatch:

Examples/BookingSystem.AspNetCore/Stores/OrderStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ public override async Task<bool> CreateOrderFromOrderProposal(OrderIdComponents
389389
sellerId.IdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
390390
orderId.uuid,
391391
version);
392-
// TODO return enum to allow errors cases to be handled in the engine
392+
// TODO return enum (something like CreateOrderStatus) to allow errors cases to be handled in the engine
393393
switch (result)
394394
{
395395
case FakeDatabaseBookOrderProposalResult.OrderSuccessfullyBooked:

Examples/BookingSystem.AspNetCore/Stores/SessionStore.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ protected override async Task GetOrderItems(List<OrderItemContext<SessionOpportu
331331
OrderItem = new OrderItem
332332
{
333333
// TODO: The static example below should come from the database (which doesn't currently support tax)
334+
// This is because it can be different for each Seller and needs to calculated at the time of booking
334335
UnitTaxSpecification = GetUnitTaxSpecification(flowContext, @class),
335336
AcceptedOffer = new Offer
336337
{
@@ -523,8 +524,8 @@ protected override async ValueTask LeaseOrderItems(
523524
}
524525
}
525526
}
526-
527-
//TODO: This should reuse code of LeaseOrderItem
527+
// TODO: This should reuse code of LeaseOrderItem to be DRY. Similar logic is also used in ProposeOrderItems as well as
528+
// in LeaseOrderItems, BookOrderItems, and ProposeOrderItems in the SessionStore. The issue for this is: https://github.com/openactive/OpenActive.Server.NET/issues/226
528529
protected override async ValueTask BookOrderItems(List<OrderItemContext<SessionOpportunity>> orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction)
529530
{
530531
// Check that there are no conflicts between the supplied opportunities
@@ -580,6 +581,8 @@ protected override async ValueTask BookOrderItems(List<OrderItemContext<SessionO
580581
// Set OrderItemId and access properties for each orderItemContext
581582
ctx.SetOrderItemId(flowContext, bookedOrderItemInfo.OrderItemId);
582583
BookedOrderItemHelper.AddPropertiesToBookedOrderItem(ctx, bookedOrderItemInfo);
584+
// Remove attendee capacity information from the OrderedItem. For more information see: https://github.com/openactive/open-booking-api/issues/156#issuecomment-926643733
585+
BookedOrderItemHelper.RemovePropertiesFromBookedOrderItem(ctx);
583586
}
584587
break;
585588
case ReserveOrderItemsResult.SellerIdMismatch:
@@ -596,7 +599,7 @@ protected override async ValueTask BookOrderItems(List<OrderItemContext<SessionO
596599
}
597600
}
598601

599-
// TODO check logic here, it's just been copied from BookOrderItems. Possibly could remove duplication here.
602+
// TODO check logic here, it's just been copied from BookOrderItems. Possibly could remove duplication here. Common logic between this, BookOrderItems, and LeaseOrderItems should be pulled out.
600603
protected override async ValueTask ProposeOrderItems(List<OrderItemContext<SessionOpportunity>> orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext, OrderTransaction databaseTransaction)
601604
{
602605
// Check that there are no conflicts between the supplied opportunities
@@ -642,6 +645,8 @@ protected override async ValueTask ProposeOrderItems(List<OrderItemContext<Sessi
642645
foreach (var (ctx, bookedOrderItemInfo) in ctxGroup.Zip(bookedOrderItemInfos, (ctx, bookedOrderItemInfo) => (ctx, bookedOrderItemInfo)))
643646
{
644647
ctx.SetOrderItemId(flowContext, bookedOrderItemInfo.OrderItemId);
648+
// Remove attendee capacity information from the OrderedItem. For more information see: https://github.com/openactive/open-booking-api/issues/156#issuecomment-926643733
649+
BookedOrderItemHelper.RemovePropertiesFromBookedOrderItem(ctx);
645650
}
646651
break;
647652
case ReserveOrderItemsResult.SellerIdMismatch:

Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static FakeDatabase()
165165
int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCount) ? opportunityCount : 2000;
166166

167167
/// <summary>
168-
/// TODO: Call this on a schedule from both .NET Core and .NET Framework reference implementations
168+
/// TODO: Call this on a schedule from both .NET Core and .NET Framework reference implementations to ensure database is not cluttered
169169
/// </summary>
170170
public async Task CleanupExpiredLeases()
171171
{
@@ -1316,7 +1316,6 @@ public static async Task RecalculateSlotUses(IDbConnection db, SlotTable slot)
13161316
slot.RemainingUses = slot.MaximumUses - totalUsesTaken;
13171317

13181318
// Push the change into the future to avoid it getting lost in the feed (see race condition transaction challenges https://developer.openactive.io/publishing-data/data-feeds/implementing-rpde-feeds#preventing-the-race-condition)
1319-
// TODO: Document this!
13201319
slot.Modified = DateTimeOffset.Now.UtcTicks;
13211320
await db.UpdateAsync(slot);
13221321
}
@@ -1343,7 +1342,7 @@ public static async Task RecalculateSpaces(IDbConnection db, OccurrenceTable occ
13431342
var totalSpacesTaken = (await db.LoadSelectAsync<OrderItemsTable>(x => x.OrderTable.OrderMode == OrderMode.Booking && x.OccurrenceId == occurrence.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent))).Count();
13441343
occurrence.RemainingSpaces = occurrence.TotalSpaces - totalSpacesTaken;
13451344

1346-
// Push the change into the future to avoid it getting lost in the feed (see race condition transaction challenges https://developer.openactive.io/publishing-data/data-feeds/implementing-rpde-feeds#preventing-the-race-condition) // TODO: Document this!
1345+
// Push the change into the future to avoid it getting lost in the feed (see race condition transaction challenges https://developer.openactive.io/publishing-data/data-feeds/implementing-rpde-feeds#preventing-the-race-condition)
13471346
occurrence.Modified = DateTimeOffset.Now.UtcTicks;
13481347
await db.UpdateAsync(occurrence);
13491348
}

OpenActive.Server.NET/CustomBookingEngine/CustomBookingEngine.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ public CustomBookingEngine(BookingEngineSettings settings, Uri openBookingAPIBas
7070
if (settings.CustomerAccountIdTemplate != null) settings.CustomerAccountIdTemplate.RequiredBaseUrl = settings.CustomerAccountIdBaseUrl;
7171

7272
// Create a lookup of each IdTemplate to pass into the appropriate RpdeGenerator
73-
// TODO: Output better error if there is a feed assigned across two templates
74-
// (there should never be, as each template represents everyting you need in one feed)
73+
// TODO: Output better error if there is a feed assigned across two templates (there should never be, as each template represents everyting you need in one feed)
7574
this.feedAssignedTemplates = settings.IdConfiguration.SelectMany(t => t.IdConfigurations.Select(x => new
7675
{
7776
assignedFeed = x.AssignedFeed,
@@ -375,7 +374,8 @@ private Guid ConvertToGuid(string uuidString)
375374
if (Guid.TryParse(uuidString, out Guid result))
376375
{
377376
return result;
378-
} else
377+
}
378+
else
379379
{
380380
throw new OpenBookingException(new OpenBookingError(), "Invalid format for Order UUID");
381381
}
@@ -424,7 +424,7 @@ public async Task<ResponseContent> ProcessOrderCreationB(string clientId, Uri se
424424
{
425425
// Attempt to use idempotency cache if it exists
426426
var cachedResponse = await GetResponseFromIdempotencyStoreIfExists(settings, orderId, orderJson);
427-
if (cachedResponse != null)
427+
if (cachedResponse != null)
428428
{
429429
return cachedResponse;
430430
}
@@ -449,7 +449,7 @@ public async Task<ResponseContent> ProcessOrderProposalCreationP(string clientId
449449
{
450450
// Attempt to use idempotency cache if it exists
451451
var cachedResponse = await GetResponseFromIdempotencyStoreIfExists(settings, orderId, orderJson);
452-
if (cachedResponse != null)
452+
if (cachedResponse != null)
453453
{
454454
return cachedResponse;
455455
}
@@ -462,7 +462,7 @@ public async Task<ResponseContent> ProcessOrderProposalCreationP(string clientId
462462

463463
private async Task<ResponseContent> GetResponseFromIdempotencyStoreIfExists(BookingEngineSettings settings, OrderIdComponents orderId, string orderJson)
464464
{
465-
// Attempt to use idempotency cache if it exists
465+
// Attempt to use idempotency cache if it exists
466466
if (settings.IdempotencyStore != null)
467467
{
468468
var cachedResponse = await settings.IdempotencyStore.GetSuccessfulOrderCreationResponse(orderId, orderJson);
@@ -474,7 +474,8 @@ private async Task<ResponseContent> GetResponseFromIdempotencyStoreIfExists(Book
474474
return null;
475475
}
476476

477-
private async Task<ResponseContent> CreateResponseViaIdempotencyStoreIfExists(BookingEngineSettings settings, OrderIdComponents orderId, string orderJson, Order response) {
477+
private async Task<ResponseContent> CreateResponseViaIdempotencyStoreIfExists(BookingEngineSettings settings, OrderIdComponents orderId, string orderJson, Order response)
478+
{
478479
// Return a 409 status code if any OrderItem level errors exist
479480
var httpStatusCode = response.OrderedItem.Exists(x => x.Error?.Count > 0) ? HttpStatusCode.Conflict : HttpStatusCode.Created;
480481
var responseJson = OpenActiveSerializer.Serialize(response);
@@ -730,6 +731,7 @@ async Task<ResponseContent> IBookingEngine.InsertTestOpportunity(string testData
730731
throw new OpenBookingException(new OpenBookingError(), "Only bookable opportunities are permitted in the test interface");
731732

732733
// TODO: add this error class to the library
734+
// CS: Does this mean add a new specific error to OpenActive.Net, something like OnlyBookableOpportunitesPermittedInTestInterfaceError
733735
}
734736

735737
if (!genericEvent.TestOpportunityCriteria.HasValue)
@@ -868,7 +870,7 @@ async Task<ResponseContent> IBookingEngine.TriggerTestAction(string actionJson)
868870

869871
// Throw error if TotalPaymentDue is not specified at B or P
870872
if (order.TotalPaymentDue?.Price.HasValue != true && (stage == FlowStage.B || stage == FlowStage.P))
871-
// TODO replace this with a more specific error
873+
// TODO replace this with a more specific error ie a subclass of OpenBookingException like TotalPaymentMissingAtBOrPError
872874
throw new OpenBookingException(new OpenBookingError(), "TotalPaymentDue must have a price set");
873875

874876
var payer = order.BrokerRole == BrokerType.ResellerBroker ? order.Broker : order.Customer;

OpenActive.Server.NET/OpenBookingHelper/IdTransforms/IdTemplate.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,20 +417,24 @@ public Uri RenderOrderId(OrderType orderType, Guid uuid)
417417
return this.RenderOrderId(new OrderIdComponents { OrderType = orderType, uuid = uuid });
418418
}
419419

420-
//TODO reduce duplication of the strings / logic below
421-
public Uri RenderOrderItemId(OrderType orderType, Guid uuid, Guid orderItemId)
420+
private void ValidateOrderType(OrderType orderType)
422421
{
423422
if (orderType != OrderType.Order) throw new ArgumentOutOfRangeException(nameof(orderType), "The Open Booking API 1.0 specification only permits OrderItem Ids to exist within Orders, not OrderQuotes or OrderProposals.");
423+
}
424+
425+
public Uri RenderOrderItemId(OrderType orderType, Guid uuid, Guid orderItemId)
426+
{
427+
ValidateOrderType(orderType);
424428
return this.RenderOrderItemId(new OrderIdComponents { OrderType = orderType, uuid = uuid, OrderItemIdGuid = orderItemId });
425429
}
426430
public Uri RenderOrderItemId(OrderType orderType, Guid uuid, string orderItemId)
427431
{
428-
if (orderType != OrderType.Order) throw new ArgumentOutOfRangeException(nameof(orderType), "The Open Booking API 1.0 specification only permits OrderItem Ids to exist within Orders, not OrderQuotes or OrderProposals.");
432+
ValidateOrderType(orderType);
429433
return this.RenderOrderItemId(new OrderIdComponents { OrderType = orderType, uuid = uuid, OrderItemIdString = orderItemId });
430434
}
431435
public Uri RenderOrderItemId(OrderType orderType, Guid uuid, long orderItemId)
432436
{
433-
if (orderType != OrderType.Order) throw new ArgumentOutOfRangeException(nameof(orderType), "The Open Booking API 1.0 specification only permits OrderItem Ids to exist within Orders, not OrderQuotes or OrderProposals.");
437+
ValidateOrderType(orderType);
434438
return this.RenderOrderItemId(new OrderIdComponents { OrderType = orderType, uuid = uuid, OrderItemIdLong = orderItemId });
435439
}
436440

OpenActive.Server.NET/OpenBookingHelper/Model/OrderModelSupport.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ protected Uri RenderOrderId(OrderType orderType, Guid uuid)
1818
return this.OrderIdTemplate.RenderOrderId(orderType, uuid);
1919
}
2020

21-
//TODO reduce duplication of the strings / logic below
2221
protected Uri RenderOrderItemId(OrderType orderType, Guid uuid, Guid orderItemId)
2322
{
2423
return this.OrderIdTemplate.RenderOrderItemId(orderType, uuid, orderItemId);

OpenActive.Server.NET/OpenBookingHelper/OrderCalculations/OrderCalculations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public static List<OpenBookingError> ValidateAdditionalDetails(OrderItem respons
145145

146146
public static Event RenderOpportunityWithOnlyId(OpportunityType opportunityType, Uri id)
147147
{
148-
// TODO: Create an extra prop in DatasetSite lib so that we don't need to parse the URL here
148+
// TODO: Create an extra property in DatasetSite library called DatasetOpportunityType so that we don't need to parse the URL here
149149
switch (OpportunityTypes.Configurations[opportunityType].SameAs.AbsolutePath.Trim('/'))
150150
{
151151
case nameof(Event):

0 commit comments

Comments
 (0)