Skip to content

Commit 971b702

Browse files
committed
feat: Adds Book API operations
Introduces the Book API operations for creating bookings. This change includes the necessary request and response models, as well as the API client extensions for interacting with the booking endpoint. A date-only JSON converter is added to correctly serialize and deserialize dates in the "yyyy-MM-dd" format.
1 parent a1ccb98 commit 971b702

File tree

7 files changed

+1695
-1
lines changed

7 files changed

+1695
-1
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// This work is licensed under the terms of the MIT license.
2+
// For a copy, see <https://opensource.org/licenses/MIT>.
3+
4+
namespace HyperGuestSDK.Api;
5+
6+
using HyperGuestSDK.Api.Book;
7+
8+
partial interface IHyperGuestApiClient
9+
{
10+
IBookOperations Book { get; }
11+
}
12+
13+
partial class HyperGuestApiClient
14+
{
15+
Lazy<IBookOperations>? _book;
16+
public IBookOperations Book => (_book ??= Defer<IBookOperations>(
17+
c => new BookOperations("/2.0/booking", c))).Value;
18+
}
19+
20+
public partial interface IBookOperations
21+
{
22+
Task<HyperGuestResponse<BookingResponse>> CreateAsync(
23+
BookRequest request,
24+
CancellationToken cancellationToken = default);
25+
}
26+
27+
/// <summary>
28+
/// Provides operations for operating on the Book domain.
29+
/// </summary>
30+
/// <param name="client">The API client.</param>
31+
public partial class BookOperations(PathString path, ApiClient client) : IBookOperations
32+
{
33+
readonly PathString _path = path;
34+
readonly ApiClient _client = client;
35+
36+
public async Task<HyperGuestResponse<BookingResponse>> CreateAsync(
37+
BookRequest request,
38+
CancellationToken cancellationToken = default)
39+
{
40+
var req = new HyperGuestRequest<BookRequest>(
41+
HyperGuestService.Book,
42+
HttpMethod.Post,
43+
_path + $"/create",
44+
request);
45+
46+
return await _client.FetchAsync<BookRequest, BookingResponse>(req, cancellationToken)
47+
.ConfigureAwait(false);
48+
}
49+
}
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
// This work is licensed under the terms of the MIT license.
2+
// For a copy, see <https://opensource.org/licenses/MIT>.
3+
4+
namespace HyperGuestSDK.Api.Book;
5+
6+
using System.Text.Json.Serialization;
7+
8+
/// <summary>
9+
/// Represents a request to book a stay.
10+
/// </summary>
11+
public class BookRequest : Model<BookRequest>
12+
{
13+
/// <summary>
14+
/// Gets or sets the from and to dates for this booking.
15+
/// </summary>
16+
[JsonPropertyName("dates"), JsonPropertyOrder(0)]
17+
public BookingDates Dates { get; set; }
18+
19+
/// <summary>
20+
/// Gets or sets the details of the lead guest associated with the booking.
21+
/// </summary>
22+
[JsonPropertyName("leadGuest"), JsonPropertyOrder(2)]
23+
public GuestDetails? LeadGuest { get; set; }
24+
25+
/// <summary>
26+
/// Gets or sets the collection of metadata key-value pairs associated with this instance.
27+
/// </summary>
28+
/// <remarks>Keys are case-sensitive. Values may be null to indicate the absence of a value for a given key. The
29+
/// dictionary itself may be null if no metadata is associated.</remarks>
30+
[JsonPropertyName("meta"), JsonPropertyOrder(6)]
31+
public Dictionary<string, string?>? Metadata { get; set; }
32+
33+
/// <summary>
34+
/// Gets or sets the payment details associated with the transaction.
35+
/// </summary>
36+
[JsonPropertyName("paymentDetails"), JsonPropertyOrder(4)]
37+
public PaymentDetails? Payment { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets the property ID to book.
41+
/// </summary>
42+
[JsonPropertyName("propertyId"), JsonPropertyOrder(1)]
43+
public int PropertyId { get; set; }
44+
45+
/// <summary>
46+
/// Gets or sets the reference details associated with this instance.
47+
/// </summary>
48+
[JsonPropertyName("reference"), JsonPropertyOrder(3)]
49+
public ReferenceDetails? Reference { get; set; }
50+
51+
/// <summary>
52+
/// Gets or sets the collection of room details associated with this instance.
53+
/// </summary>
54+
[JsonPropertyName("rooms"), JsonPropertyOrder(5)]
55+
public List<RoomDetails>? Rooms { get; set; }
56+
}
57+
58+
/// <summary>
59+
/// Represents a range of dates for a booking, including the start and end dates.
60+
/// </summary>
61+
/// <param name="From">The start date of the booking period. Represents the inclusive beginning of the date range.</param>
62+
/// <param name="To">The end date of the booking period. Represents the inclusive end of the date range.</param>
63+
public record BookingDates(
64+
[property: JsonPropertyName("from"), JsonConverter(typeof(DateOnlyJsonConverter))] DateTime From,
65+
[property: JsonPropertyName("to"), JsonConverter(typeof(DateOnlyJsonConverter))] DateTime To
66+
);
67+
68+
/// <summary>
69+
/// Represents the personal and contact details of a guest, including name, title, date of birth, and contact
70+
/// information.
71+
/// </summary>
72+
public class GuestDetails
73+
{
74+
/// <summary>
75+
/// Gets or sets the date of birth.
76+
/// </summary>
77+
[JsonPropertyName("birthDate"), JsonPropertyOrder(0)]
78+
public DateTime BirthDate { get; set; }
79+
80+
/// <summary>
81+
/// Gets or sets the contact information associated with this entity.
82+
/// </summary>
83+
[JsonPropertyName("contact"), JsonPropertyOrder(1)]
84+
public ContactDetails? Contact { get; set; }
85+
86+
/// <summary>
87+
/// Gets or sets the name details associated with the entity.
88+
/// </summary>
89+
[JsonPropertyName("name"), JsonPropertyOrder(2)]
90+
public NameDetails? Name { get; set; }
91+
92+
/// <summary>
93+
/// Gets or sets the title associated with the object.
94+
/// </summary>
95+
[JsonPropertyName("title"), JsonPropertyOrder(3)]
96+
public string? Title { get; set; }
97+
}
98+
99+
/// <summary>
100+
/// Represents a set of contact information, including address, phone number, and email details.
101+
/// </summary>
102+
/// <remarks>Use this class to store or transfer contact details for an individual or organization. All properties
103+
/// are optional and may be left unset if the corresponding information is not available.</remarks>
104+
public class ContactDetails
105+
{
106+
/// <summary>
107+
/// Gets or sets the address associated with the entity.
108+
/// </summary>
109+
[JsonPropertyName("address"), JsonPropertyOrder(0)]
110+
public string? Address { get; set; }
111+
112+
/// <summary>
113+
/// Gets or sets the city associated with the entity.
114+
/// </summary>
115+
[JsonPropertyName("city"), JsonPropertyOrder(1)]
116+
public string? City { get; set; }
117+
118+
/// <summary>
119+
/// Gets or sets the country associated with the entity.
120+
/// </summary>
121+
[JsonPropertyName("country"), JsonPropertyOrder(2)]
122+
public string? Country { get; set; }
123+
124+
/// <summary>
125+
/// Gets or sets the email address associated with the user.
126+
/// </summary>
127+
[JsonPropertyName("email"), JsonPropertyOrder(3)]
128+
public string? Email { get; set; }
129+
130+
/// <summary>
131+
/// Gets or sets the phone number associated with the contact.
132+
/// </summary>
133+
[JsonPropertyName("phone"), JsonPropertyOrder(4)]
134+
public string? Phone { get; set; }
135+
136+
/// <summary>
137+
/// Gets or sets the state or province associated with the entity.
138+
/// </summary>
139+
[JsonPropertyName("state"), JsonPropertyOrder(5)]
140+
public string? State { get; set; }
141+
142+
/// <summary>
143+
/// Gets or sets the postal code associated with the address.
144+
/// </summary>
145+
[JsonPropertyName("zip"), JsonPropertyOrder(6)]
146+
public string? Zip { get; set; }
147+
}
148+
149+
/// <summary>
150+
/// Represents a person's name, including first and last name components.
151+
/// </summary>
152+
public class NameDetails
153+
{ /// <summary>
154+
/// Gets or sets the first name.
155+
/// </summary>
156+
[JsonPropertyName("first"), JsonPropertyOrder(0)]
157+
public string? First { get; set; }
158+
159+
/// <summary>
160+
/// Gets or sets the last name.
161+
/// </summary>
162+
[JsonPropertyName("last"), JsonPropertyOrder(1)]
163+
public string? Last { get; set; }
164+
}
165+
166+
/// <summary>
167+
/// Represents details about a reference, including agency information.
168+
/// </summary>
169+
public class ReferenceDetails
170+
{
171+
/// <summary>
172+
/// Gets or sets the agency details
173+
/// </summary>
174+
[JsonPropertyName("agency"), JsonPropertyOrder(0)]
175+
public string? Agency { get; set; }
176+
}
177+
178+
/// <summary>
179+
/// Represents information about a payment, including its type and associated details.
180+
/// </summary>
181+
public class PaymentDetails
182+
{
183+
/// <summary>
184+
/// Gets or sets additional details about the payment type.
185+
/// </summary>
186+
[JsonPropertyName("details"), JsonPropertyOrder(1)]
187+
public PaymentTypeDetails? Details { get; set; }
188+
189+
/// <summary>
190+
/// Gets or sets the payment type.
191+
/// </summary>
192+
[JsonPropertyName("type"), JsonPropertyOrder(0)]
193+
public string? Type { get; set; }
194+
}
195+
196+
/// <summary>
197+
/// Represents details about a specific payment type.
198+
/// </summary>
199+
[JsonDerivedType(typeof(CardPaymentDetails))]
200+
public abstract class PaymentTypeDetails
201+
{
202+
203+
}
204+
205+
/// <summary>
206+
/// Defines the potential payment types.
207+
/// </summary>
208+
public static class PaymentType
209+
{
210+
/// <summary>
211+
/// The payment type is a card payment.
212+
/// </summary>
213+
public const string Card = "credit_card";
214+
215+
/// <summary>
216+
/// The payment type is an external payment.
217+
/// </summary>
218+
public const string External = "external";
219+
}
220+
221+
/// <summary>
222+
/// Represents the details required to process a card payment, including card number, expiration, cardholder name, and
223+
/// CVV.
224+
/// </summary>
225+
/// <remarks>Use this class to provide card-specific information when initiating a payment. All properties should
226+
/// be populated with valid card data as required by the payment processor. Sensitive information such as card number
227+
/// and CVV should be handled securely and in compliance with applicable data protection standards.</remarks>
228+
public class CardPaymentDetails : PaymentTypeDetails
229+
{
230+
/// <summary>
231+
/// Gets or sets a value indicating whether a charge should be applied.
232+
/// </summary>
233+
[JsonPropertyName("charge"), JsonPropertyOrder(4)]
234+
public bool Charge { get; set; }
235+
236+
/// <summary>
237+
/// Gets or sets the card's CVV (Card Verification Value).
238+
/// </summary>
239+
[JsonPropertyName("cvv"), JsonPropertyOrder(1)]
240+
public string? Cvv { get; set; }
241+
242+
/// <summary>
243+
/// Gets or sets the card's expiration details.
244+
/// </summary>
245+
[JsonPropertyName("expiry"), JsonPropertyOrder(2)]
246+
public CardExpiryDetails? Expiry { get; set; }
247+
248+
/// <summary>
249+
/// Gets or sets the name on the card.
250+
/// </summary>
251+
[JsonPropertyName("name"), JsonPropertyOrder(3)]
252+
public NameDetails? Name { get; set; }
253+
254+
/// <summary>
255+
/// Gets or sets the card number.
256+
/// </summary>
257+
[JsonPropertyName("number"), JsonPropertyOrder(0)]
258+
public string? Number { get; set; }
259+
}
260+
261+
/// <summary>
262+
/// Represents details about the expiry of a card.
263+
/// </summary>
264+
public class CardExpiryDetails
265+
{
266+
/// <summary>
267+
/// Gets or sets the card expiry month.
268+
/// </summary>
269+
[JsonPropertyName("month"), JsonPropertyOrder(0)]
270+
public int Month { get; set; }
271+
272+
/// <summary>
273+
/// Gets or sets the card expiry year.
274+
/// </summary>
275+
[JsonPropertyName("year"), JsonPropertyOrder(1)]
276+
public int Year { get; set; }
277+
}
278+
279+
/// <summary>
280+
/// Represents the details of a room, including pricing and identification information, for use in transactions.
281+
/// </summary>
282+
public class RoomDetails
283+
{
284+
/// <summary>
285+
/// Gets or sets the expected price details for the transaction.
286+
/// </summary>
287+
[JsonPropertyName("expectedPrice"), JsonPropertyOrder(2)]
288+
public PriceDetails? ExpectedPrice { get; set; }
289+
290+
/// <summary>
291+
/// Gets or sets the collection of guest details associated with the current entity.
292+
/// </summary>
293+
[JsonPropertyName("guests"), JsonPropertyOrder(3)]
294+
public GuestDetails[]? Guests { get; set; }
295+
296+
/// <summary>
297+
/// Gets or sets the rate code associated with this entity.
298+
/// </summary>
299+
[JsonPropertyName("rateCode"), JsonPropertyOrder(1)]
300+
public string? RateCode { get; set; }
301+
302+
/// <summary>
303+
/// Gets or sets the unique code that identifies the room.
304+
/// </summary>
305+
[JsonPropertyName("roomCode"), JsonPropertyOrder(0)]
306+
public string? RoomCode { get; set; }
307+
308+
/// <summary>
309+
/// Gets or sets the unique identifier of the room. If this value is provided <see cref="RoomCode"/> is ignored.
310+
/// </summary>
311+
[JsonPropertyName("roomId"), JsonPropertyOrder(0)]
312+
public int? RoomId { get; set; }
313+
314+
/// <summary>
315+
/// Gets or sets the list of special requests associated with the booking.
316+
/// </summary>
317+
[JsonPropertyName("specialRequests"), JsonPropertyOrder(4)]
318+
public List<string>? SpecialRequests { get; set; }
319+
}
320+
321+
/// <summary>
322+
/// Represents pricing information, including the total amount and its associated currency.
323+
/// </summary>
324+
public class PriceDetails
325+
{
326+
/// <summary>
327+
/// Gets or sets the total amount.
328+
/// </summary>
329+
[JsonPropertyName("amount"), JsonPropertyOrder(0)]
330+
public decimal Amount { get; set; }
331+
332+
/// <summary>
333+
/// Gets or sets the currency associated with the price.
334+
/// </summary>
335+
[JsonPropertyName("currency"), JsonPropertyOrder(1)]
336+
public string? Currency { get; set; }
337+
}

0 commit comments

Comments
 (0)