Skip to content

Commit

Permalink
feat: Add support for basket items
Browse files Browse the repository at this point in the history
  • Loading branch information
Antaris committed Feb 13, 2024
1 parent 93decd5 commit 7d658b0
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 4 deletions.
25 changes: 24 additions & 1 deletion apps/TrybeSDK.ConsoleSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
var api = new TrybeApiClient(http, settings);
var frontend = new TrybeFrontendClient(http, settings);

// MA - Create a booking frame.
var bookingFrame = await frontend.BookingFrames.CreateBookingFrameAsync(
new CreateBookingFrameRequest
{
Expand All @@ -30,7 +31,29 @@
}
});

Console.WriteLine(bookingFrame);
string basketId = bookingFrame.Data.Basket.Id;

// MA - Add an item to the basket.
var itemResponse = await api.Shop.Baskets.AddBasketItemAsync(
basketId,
new AddBasketItemRequest
{
OfferingId = "6372bc492ea8f57d2508fe82",
OfferingType = "package",
Date = new(2024, 04, 02),
Quantity = 1,
Guests = bookingFrame.Data.Basket.Guests
});

string basketItemId = itemResponse.Data.Items[0].Id;

itemResponse = await api.Shop.Baskets.DeleteBasketItemAsync(
basketId,
basketItemId);

// MA - Fetch the basket.
var response = await api.Shop.Baskets.GetBasketAsync(bookingFrame.Data!.Basket!.Id);
Console.WriteLine(response.Data);

TrybeSettings GetSettings()
{
Expand Down
204 changes: 204 additions & 0 deletions libs/TrybeSDK/Api/Shop/Basket/BasketOperations.Items.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.

using System.Text.Json.Serialization;

using TrybeSDK.Primitives;

namespace TrybeSDK.Api;

partial interface IBasketOperations
{
/// <summary>
/// Adds an item to the basket.
/// HTTP POST /shop/basket/{basketId}/items
/// </summary>
/// <param name="basketId">The ID of the basket.</param>
/// <param name="request">The request representing the add operation.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The updated basket instance.</returns>
Task<TrybeResponse<Basket>> AddBasketItemAsync(
string basketId,
AddBasketItemRequest request,
CancellationToken cancellationToken = default);

/// <summary>
/// Deletes an item to the basket.
/// HTTP DELETE /shop/basket/{basketId}/items/{basketItemId}
/// </summary>
/// <param name="basketId">The ID of the basket.</param>
/// <param name="basketItemId">The ID of the basket item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The updated basket instance.</returns>
Task<TrybeResponse<Basket>> DeleteBasketItemAsync(
string basketId,
string basketItemId,
CancellationToken cancellationToken = default);

/// <summary>
/// Updates an item to the basket.
/// HTTP PUT /shop/basket/{basketId}/items/{basketItemId}
/// </summary>
/// <param name="basketId">The ID of the basket.</param>
/// <param name="basketItemId">The ID of the basket item.</param>
/// <param name="request">The request representing the update operation.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The updated basket instance.</returns>
Task<TrybeResponse<Basket>> UpdateBasketItemAsync(
string basketId,
string basketItemId,
UpdateBasketItemRequest request,
CancellationToken cancellationToken = default);
}

partial class BasketOperations
{
public async Task<TrybeResponse<Basket>> AddBasketItemAsync(
string basketId,
AddBasketItemRequest itemRequest,
CancellationToken cancellationToken = default)
{
Ensure.IsNotNullOrEmpty(basketId, nameof(basketId));
Ensure.IsNotNull(itemRequest, nameof(itemRequest));

var request = new TrybeRequest<AddBasketItemRequest>(HttpMethod.Post, path + $"/{basketId}/items", itemRequest);

return await client.FetchAsync<AddBasketItemRequest, Basket>(request, cancellationToken);
}

public async Task<TrybeResponse<Basket>> DeleteBasketItemAsync(
string basketId,
string basketItemId,
CancellationToken cancellationToken = default)
{
Ensure.IsNotNullOrEmpty(basketId, nameof(basketId));
Ensure.IsNotNullOrEmpty(basketItemId, nameof(basketItemId));

var request = new TrybeRequest(HttpMethod.Delete, path + $"/{basketId}/items/{basketItemId}");

return await client.FetchAsync<Basket>(request, cancellationToken);
}

public async Task<TrybeResponse<Basket>> UpdateBasketItemAsync(
string basketId,
string basketItemId,
UpdateBasketItemRequest itemRequest,
CancellationToken cancellationToken = default)
{
Ensure.IsNotNullOrEmpty(basketId, nameof(basketId));
Ensure.IsNotNullOrEmpty(basketItemId, nameof(basketItemId));
Ensure.IsNotNull(itemRequest, nameof(itemRequest));

var request = new TrybeRequest<UpdateBasketItemRequest>(HttpMethod.Put, path + $"/{basketId}/items/{basketItemId}", itemRequest);

return await client.FetchAsync<UpdateBasketItemRequest, Basket>(request, cancellationToken);
}
}

/// <summary>
/// Represents a request to add a new basket item.
/// </summary>
public class AddBasketItemRequest
{
/// <summary>
/// The date selected for the offering, if applicable.
/// </summary>
[JsonPropertyName("date")]
public DateTime? Date { get; set; }

/// <summary>
/// The duration selected for the offering, if applicable.
/// </summary>
[JsonPropertyName("duration")]
public int? Duration { get; set; }

/// <summary>
/// The set of guests associated with this offering.
/// </summary>
[JsonPropertyName("guests")]
public GuestList? Guests { get; set; }

/// <summary>
/// The set of custom item configuration settings.
/// </summary>
[JsonPropertyName("item_configuration")]
public ObjectDictionary? ItemConfiguration { get; set; }

/// <summary>
/// The ID of the offering.
/// </summary>
[JsonPropertyName("offering_id")]
public required string OfferingId { get; init; }

/// <summary>
/// The type of item being added.
/// </summary>
[JsonPropertyName("offering_type")]
public required string OfferingType { get; init; }

/// <summary>
/// The overriden price, if applicable.
/// </summary>
[JsonPropertyName("price")]
public int? Price { get; set; }

/// <summary>
/// The quantity required of the offering, if applicable.
/// </summary>
[JsonPropertyName("quantity")]
public int? Quantity { get; set; }

/// <summary>
/// The time selected for the offering, if applicable.
/// </summary>
[JsonPropertyName("time")]
public TimeSpan? Time { get; set; }
}

/// <summary>
/// Represents a request to add a new basket item.
/// </summary>
public class UpdateBasketItemRequest
{
/// <summary>
/// The date selected for the offering, if applicable.
/// </summary>
[JsonPropertyName("date")]
public DateTime? Date { get; set; }

/// <summary>
/// The duration selected for the offering, if applicable.
/// </summary>
[JsonPropertyName("duration")]
public int? Duration { get; set; }

/// <summary>
/// The set of guests associated with this offering.
/// </summary>
[JsonPropertyName("guests")]
public GuestList? Guests { get; set; }

/// <summary>
/// The set of custom item configuration settings.
/// </summary>
[JsonPropertyName("item_configuration")]
public ObjectDictionary? ItemConfiguration { get; set; }

/// <summary>
/// The overriden price, if applicable.
/// </summary>
[JsonPropertyName("price")]
public int? Price { get; set; }

/// <summary>
/// The quantity required of the offering, if applicable.
/// </summary>
[JsonPropertyName("quantity")]
public int? Quantity { get; set; }

/// <summary>
/// The time selected for the offering, if applicable.
/// </summary>
[JsonPropertyName("time")]
public TimeSpan? Time { get; set; }
}
50 changes: 50 additions & 0 deletions libs/TrybeSDK/Api/Shop/Basket/BasketOperations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.

namespace TrybeSDK.Api;

partial interface IShopOperations
{
/// <summary>
/// Gets the /shop/basket operations.
/// </summary>
IBasketOperations Baskets { get; }
}

partial class ShopOperations
{
Lazy<IBasketOperations> _baskets;
public IBasketOperations Baskets => (_baskets ??= client.Defer<IBasketOperations>(
c => new BasketOperations(path + "/basket", c))).Value;
}

/// <summary>
/// Provides operations for operating on the /shop/basket endpoint.
/// </summary>
public partial interface IBasketOperations
{
/// <summary>
/// Gets the basket with the given ID.
/// HTTP GET /shop/basket/{basketId}
/// </summary>
/// <param name="basketId">The basket ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The basket instance.</returns>
Task<TrybeResponse<Basket>> GetBasketAsync(
string basketId,
CancellationToken cancellationToken = default);
}

public partial class BasketOperations(PathString path, ApiClient client): IBasketOperations
{
public async Task<TrybeResponse<Basket>> GetBasketAsync(
string basketId,
CancellationToken cancellationToken = default)
{
Ensure.IsNotNullOrEmpty(basketId, nameof(basketId));

var request = new TrybeRequest(HttpMethod.Get, path + $"/{basketId}");

return await client.FetchAsync<Basket>(request, cancellationToken);
}
}
1 change: 1 addition & 0 deletions libs/TrybeSDK/Api/Sites/SiteOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public partial interface ISiteOperations
{
/// <summary>
/// Deletes the site with the given ID.
/// HTTP DELETE /site/{siteId}
/// </summary>
/// <param name="siteId">The site ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
Expand Down
4 changes: 2 additions & 2 deletions libs/TrybeSDK/Frontend/BookingFrame/BookingFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ public class CreateBookingFrameRequest
/// <summary>
/// The minimum date for offerings.
/// </summary>
[JsonPropertyName("date_from"), JsonConverter(typeof(DateFormatJsonConverter))]
[JsonPropertyName("date_from")]
public required DateTime DateFrom { get; init; }

/// <summary>
/// The maximum date for offerings.
/// </summary>
[JsonPropertyName("date_to"), JsonConverter(typeof(DateFormatJsonConverter))]
[JsonPropertyName("date_to")]
public required DateTime DateTo { get; init; }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public partial interface IBookingFrameOperations
{
/// <summary>
/// Creates a booking frame.
/// HTTP POST /booking-frame/create
/// </summary>
/// <param name="request">The create booking frame request.</param>
/// <param name="cancellationToken">The cancellation token.</param>
Expand Down
4 changes: 4 additions & 0 deletions libs/TrybeSDK/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@

global using StringDictionary = System.Collections.Generic.Dictionary<string, string>;
global using StringPair = System.Collections.Generic.KeyValuePair<string, string>;

global using ObjectDictionary = System.Collections.Generic.Dictionary<string, object>;

global using GuestList = System.Collections.Generic.List<TrybeSDK.Api.Guest>;
4 changes: 4 additions & 0 deletions libs/TrybeSDK/JsonUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;

using TrybeSDK.Primitives;

namespace TrybeSDK;

static class JsonUtility
Expand All @@ -16,6 +18,8 @@ public static JsonSerializerOptions CreateSerializerOptions()
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

options.Converters.Add(new DateFormatJsonConverter());

return options;
}

Expand Down
2 changes: 1 addition & 1 deletion libs/TrybeSDK/TrybeResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class TrybeResponse(
/// <summary>
/// Gets the rate limiting metdata for the request.
/// </summary>
public RateLimiting? rateLimiting1 => rateLimiting;
public RateLimiting? RateLimiting => rateLimiting;

/// <summary>
/// Gets or sets the request HTTP method.
Expand Down

0 comments on commit 7d658b0

Please sign in to comment.