Skip to content

Commit

Permalink
feat: Add support for Shop offerings and Packages
Browse files Browse the repository at this point in the history
  • Loading branch information
Antaris committed Feb 14, 2024
1 parent fd68a4b commit 64dcfef
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 82 deletions.
83 changes: 1 addition & 82 deletions apps/TrybeSDK.ConsoleSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,89 +12,8 @@
var settings = GetSettings();
var http = CreateHttpClient();
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
{
PartnerId = settings.PartnerId!,
ReservationId = "MA-TEST-001",
DateFrom = new(2024,04,01),
DateTo = new(2024,04,01),
NumberOfGuests = 1,
ConfigureOnlyMode = true,
HidePrices = true,
Language = new StringDictionary
{
["continue_button"] = "add_to_basket"
}
});

string basketId = bookingFrame.Data.Basket.Id;

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

var guest = basket.Data.Guests[0];
guest.Name = "Matthew Abbott";
guest.IsLeadBooker = true;

await api.Shop.Baskets.UpdateBasketGuestsAsync(
basketId,
new UpdateBasketGuestsRequest
{
Guests = basket.Data.Guests
});

await api.Shop.Baskets.SetCustomerAsync(
basketId,
new Customer
{
FirstName = "Matthew",
LastName = "Abbott",
Email = "[email protected]",
HasPassword = false,
Phone = "07944747565"
});

await api.Shop.Baskets.ReserveBasketAsync(
basketId);

var orderResponse = await api.Shop.Orders.SubmitOrderAsync(
basketId);

string orderId = orderResponse.Data.Id;

await api.Shop.Orders.AddNoteAsync(
orderId!,
"Matt's Test Note");

var response = await api.Shop.Orders.AddPaymentAsync(
orderId,
new AddPaymentRequest
{
Amount = basket.Data.TotalCost.Value,
Status = "paid",
Processor = "partner",
ProcessorData = new ObjectDictionary
{
["order_ref"] = "123456",
["booking_ref"] = "B12345",
["commission_total"] = 10,
["commission_vat"] = 2,
["commission_vat_rule"] = "inc"
}
});
var response = await api.Shop.Packages.GetPackageAsync("6372bc492ea8f57d2508fe82");

Console.WriteLine(response);

Expand Down
16 changes: 16 additions & 0 deletions libs/TrybeSDK/Api/Shop/Offerings/OfferingEmailOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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;

namespace TrybeSDK.Api;

public class OfferingEmailOptions
{
/// <summary>
/// Enable to hide prices from customer emails, in cases where the customer didn't purchase the item directly.
/// </summary>
/// <value>Enable to hide prices from customer emails, in cases where the customer didn't purchase the item directly.</value>
[JsonPropertyName("hide_prices")]
public bool? HidePrices { get; set; }
}
44 changes: 44 additions & 0 deletions libs/TrybeSDK/Api/Shop/Offerings/OfferingIdentifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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;

namespace TrybeSDK.Api;

public class OfferingIdentifier
{
/// <summary>
/// The type of the offering.
/// </summary>
/// <value>The type of the offering.</value>
[JsonPropertyName("offering_type")]
public required string OfferingType { get; set; }

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

/// <summary>
/// The name of the offering.
/// </summary>
/// <value>The name of the offering.</value>
[JsonPropertyName("offering_name")]
public string? OfferingName { get; set; }

/// <summary>
/// Any additional configuration for this offering such as a fixed duration.
/// </summary>
/// <value>Any additional configuration for this offering such as a fixed duration.</value>
[JsonPropertyName("offering_config")]
public ObjectDictionary? OfferingConfig { get; set; }

/// <summary>
/// The name of the offering including any additional configuration.
/// </summary>
/// <value>The name of the offering including any additional configuration.</value>
[JsonPropertyName("display_name")]
public string? DisplayName { get; set; }
}
56 changes: 56 additions & 0 deletions libs/TrybeSDK/Api/Shop/Offerings/OfferingOperations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// 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/shop/offerings operations.
/// </summary>
IOfferingOperations Offerings { get; }
}

partial class ShopOperations
{
Lazy<IOfferingOperations> _offerings;
public IOfferingOperations Offerings => (_offerings ??= client.Defer<IOfferingOperations>(
c => new OfferingOperations(path + "/shop/offerings", client))).Value;
}

public interface IOfferingOperations
{
/// <summary>
/// Gets the offerings available for the given partner.
/// HTTP GET /shop/shop/offerings
/// </summary>
/// <param name="siteId">The site ID.</param>
/// <param name="partnerId">The partner ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The set of offerings.</returns>
Task<TrybeResponse<ShopOffering[]>> GetPartnerOfferingsAsync(
string siteId,
string partnerId,
CancellationToken cancellationToken = default);
}

public class OfferingOperations(PathString path, ApiClient client) : IOfferingOperations
{
public async Task<TrybeResponse<ShopOffering[]>> GetPartnerOfferingsAsync(
string siteId,
string partnerId,
CancellationToken cancellationToken = default)
{
Ensure.IsNotNullOrEmpty(siteId, nameof(siteId));
Ensure.IsNotNullOrEmpty(partnerId, nameof(partnerId));

var query = new QueryStringBuilder()
.AddParameter("site_id", siteId)
.AddParameter("parnter_id", partnerId)
.Build();

var request = new TrybeRequest(HttpMethod.Get, path, query);

return await client.FetchAsync<ShopOffering[]>(request);
}
}
23 changes: 23 additions & 0 deletions libs/TrybeSDK/Api/Shop/Offerings/OfferingRevenueAllocation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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;

namespace TrybeSDK.Api;

public class OfferingRevenueAllocation
{
/// <summary>
/// The identifier of the revenue centre.
/// </summary>
/// <value>The identifier of the revenue centre.</value>
[JsonPropertyName("revenue_centre")]
public string? RevenueCentre { get; set; }

/// <summary>
/// The amount to be allocated
/// </summary>
/// <value>The amount to be allocated</value>
[JsonPropertyName("amount")]
public int? Amount { get; set; }
}
126 changes: 126 additions & 0 deletions libs/TrybeSDK/Api/Shop/Offerings/ShopOffering.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.

using System.Diagnostics;
using System.Text.Json.Serialization;

namespace TrybeSDK.Api;

[DebuggerDisplay("{ToDebuggerString(),nq}")]
public class ShopOffering
{
/// <summary>
/// The ID of the offering
/// </summary>
/// <value>The ID of the offering</value>
[JsonPropertyName("id")]
public required string Id { get; set; }

/// <summary>
/// The name of the offering
/// </summary>
/// <value>The name of the offering</value>
[JsonPropertyName("name")]
public required string Name { get; set; }

/// <summary>
/// The name of the offering
/// </summary>
/// <value>The name of the offering</value>
[JsonPropertyName("description")]
public string? Description { get; set; }

/// <summary>
/// The minimum price of the offering on the given date
/// </summary>
/// <value>The minimum price of the offering on the given date</value>
[JsonPropertyName("price_from")]
public int? PriceFrom { get; set; }

/// <summary>
/// The maximum price of the offering on the given date
/// </summary>
/// <value>The maximum price of the offering on the given date</value>
[JsonPropertyName("price_to")]
public int? PriceTo { get; set; }

/// <summary>
/// If set, a discounted 'price from' that applies to the current customer
/// </summary>
/// <value>If set, a discounted 'price from' that applies to the current customer</value>
[JsonPropertyName("discounted_price_from")]
public int? DiscountedPriceFrom { get; set; }

/// <summary>
/// The currency code for the price
/// </summary>
/// <value>The currency code for the price</value>
[JsonPropertyName("currency")]
public string? Currency { get; set; }

/// <summary>
/// The duration of the offering in minutes
/// </summary>
/// <value>The duration of the offering in minutes</value>
[JsonPropertyName("duration")]
public int? Duration { get; set; }

/// <summary>
/// Gets or Sets Durations
/// </summary>

[JsonPropertyName("durations")]
public List<int>? Durations { get; set; }

/// <summary>
/// Identifies the type of this model
/// </summary>
/// <value>Identifies the type of this model</value>
[JsonPropertyName("type")]
public string? Type { get; set; }

/// <summary>
/// Whether there is availability for the offering on the requested date.
/// </summary>
/// <value>Whether there is availability for the offering on the requested date.</value>
[JsonPropertyName("has_availability")]
public bool? HasAvailability { get; set; }

/// <summary>
/// The next available date if there is no availability on the given date
/// </summary>
/// <value>The next available date if there is no availability on the given date</value>
[JsonPropertyName("next_available_date")]
public DateTime? NextAvailableDate { get; set; }

/// <summary>
/// An array of choices for items which may be included in this package
/// </summary>
/// <value>An array of choices for items which may be included in this package</value>
[JsonPropertyName("item_choices")]
public List<PackageItemChoice>? ItemChoices { get; set; }

/// <summary>
/// The minimum guests this offering is for
/// </summary>
/// <value>The minimum guests this offering is for</value>

[JsonPropertyName("min_guests")]
public int? MinGuests { get; set; }

/// <summary>
/// The maximum guests this offering is for
/// </summary>
/// <value>The maximum guests this offering is for</value>

[JsonPropertyName("max_guests")]
public int? MaxGuests { get; set; }

/// <summary>
/// Gets or Sets Categories
/// </summary>
[JsonPropertyName("categories")]
public List<ShopOfferingCategories>? Categories { get; set; }

public string ToDebuggerString() => $"{Name} ({Id})";
}
25 changes: 25 additions & 0 deletions libs/TrybeSDK/Api/Shop/Offerings/ShopOfferingCategories.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.

using System.Diagnostics;
using System.Text.Json.Serialization;

namespace TrybeSDK.Api;

[DebuggerDisplay("{Name,nq} ({Id,nq})")]
public class ShopOfferingCategories
{
/// <summary>
/// The ID of the category
/// </summary>
/// <value>The ID of the category</value>
[JsonPropertyName("id")]
public required string Id { get; set; }

/// <summary>
/// The name of the category
/// </summary>
/// <value>The name of the category</value>
[JsonPropertyName("name")]
public string? Name { get; set; }
}

0 comments on commit 64dcfef

Please sign in to comment.