Skip to content

Commit c4e00dc

Browse files
committed
feat: Implements reservation processing
Adds reservation processing functionality to the API client, including request validation and response handling. Introduces new data structures for reservation requests and responses, and enhances the API client to support reservation operations, and property retrievals.
1 parent f6de4f9 commit c4e00dc

File tree

13 files changed

+819
-481
lines changed

13 files changed

+819
-481
lines changed

apps/GuestLineSDK.ConsoleSample/Program.cs

Lines changed: 45 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,55 @@
1313
var http = CreateHttpClient();
1414
var api = new GuestLineApiClient(http, settings);
1515

16+
var prop = await api.Service.GetPropertyAsync("12992");
17+
1618
var ari = await api.Service.GetAriAsync(new GuestLineAriRequest(
1719
PropertyId: "12992",
1820
RoomId: "1299210STANDARD",
1921
RateId: "1299224125",
20-
Action: AriAction.FullYear));
22+
AriAction: AriAction.Range,
23+
Start: new(2026, 02, 15),
24+
End: new(2026, 02, 15)
25+
));
26+
27+
var res = new ReservationRequest(
28+
DateTime.UtcNow,
29+
"X12345",
30+
0,
31+
"Hotel Collect",
32+
999.99m,
33+
Math.Round(999.99m / 6),
34+
prop.Data!.CurrencyCode!,
35+
"Confirm",
36+
new ReservationCustomer
37+
{
38+
FirstName = "Matthew",
39+
LastName = "Abbott"
40+
},
41+
[
42+
new ReservationRoom(
43+
new(2026, 02, 15),
44+
new(2026, 02, 16),
45+
"1299210STANDARD",
46+
[
47+
new ReservationRate(
48+
new(2026, 02, 15),
49+
"1299224125",
50+
999.99m)
51+
],
52+
"Matthew",
53+
"Abbott",
54+
"Test Order",
55+
999.99m,
56+
1,
57+
0)
58+
],
59+
"SpaSeekers");
60+
61+
var reservationResult = await api.Reservation.ProcessReservationAsync(
62+
new GuestLineReservationRequest(
63+
"12992",
64+
[res]));
2165

2266
//string json = GetARIUpdate();
2367

@@ -48,82 +92,3 @@ HttpClient CreateHttpClient()
4892

4993
return http;
5094
}
51-
52-
string GetARIUpdate()
53-
{
54-
return @"{
55-
""propertyid"": ""934001"",
56-
""room_id"": ""10512556XPQ3"",
57-
""rate_id"": ""STAAH194181"",
58-
""currency"": ""INR"",
59-
""apikey"": ""GeT-aPi-DemoY-U1V8-bdt-03gEp-u1D8a4Y"",
60-
""data"": [
61-
{
62-
""cta"": ""N"",
63-
""amountAfterTax"": {
64-
""extrachild"": ""600"",
65-
""Rate"": ""4900"",
66-
""obp"": {
67-
""person2"": ""5405"",
68-
""person3"": ""5700"",
69-
""person1"": ""4900""
70-
},
71-
""extraadult"": ""800""
72-
},
73-
""minstay"": ""1"",
74-
""from_date"": ""2024-08-22"",
75-
""to_date"": ""2024-08-22"",
76-
""stopsell"": ""N"",
77-
""amountBeforeTax"": {
78-
""Rate"": ""4900"",
79-
""extrachild"": ""600.00"",
80-
""extraadult"": ""800.00"",
81-
""obp"": {
82-
""person2"": ""5400"",
83-
""person3"": ""5700"",
84-
""person1"": ""4900""
85-
}
86-
},
87-
""ctd"": ""N"",
88-
""inventory"": ""9"",
89-
""maxstay"": ""28"",
90-
""minstay_through"": ""1"",
91-
""maxstay_through"": ""3""
92-
},
93-
{
94-
""minstay"": ""1"",
95-
""amountAfterTax"": {
96-
""obp"": {
97-
""person1"": ""4900"",
98-
""person3"": ""5700"",
99-
""person2"": ""5400""
100-
},
101-
""extraadult"": ""800"",
102-
""Rate"": ""4900"",
103-
""extrachild"": ""600""
104-
},
105-
""cta"": ""N"",
106-
""stopsell"": ""N"",
107-
""from_date"": ""2024-08-24"",
108-
""to_date"": ""2024-08-24"",
109-
""amountBeforeTax"": {
110-
""extrachild"": ""600.00"",
111-
""Rate"": ""4900"",
112-
""obp"": {
113-
""person3"": ""5758"",
114-
""person1"": ""4900"",
115-
""person2"": ""5400""
116-
},
117-
""extraadult"": ""800.00""
118-
},
119-
""ctd"": ""N"",
120-
""maxstay"": ""28"",
121-
""inventory"": ""9"",
122-
""minstay_through"": ""1"",
123-
""maxstay_through"": ""3""
124-
}
125-
],
126-
""trackingId"": ""FA81B5AD-E050-4501-81C9-E33EAD371762"",
127-
""version"": ""2""
128-
}";
129-
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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 GuestLineSDK.Api;
5+
6+
using System.Text.Json.Serialization;
7+
8+
using FluentValidation;
9+
10+
using GuestLineSDK.Ari;
11+
using GuestLineSDK.Primitives;
12+
13+
partial interface IGuestLineApiClient
14+
{
15+
/// <summary>
16+
/// Reservation Operations
17+
/// </summary>
18+
IReservationOperations Reservation { get; }
19+
}
20+
21+
partial class GuestLineApiClient
22+
{
23+
Lazy<IReservationOperations>? _reservation;
24+
public IReservationOperations Reservation => (_reservation ??= Defer<IReservationOperations>(
25+
c => new ReservationOperations(c))).Value;
26+
}
27+
28+
public partial interface IReservationOperations
29+
{
30+
Task<GuestLineResponse<ReservationRef>> ProcessReservationAsync(
31+
GuestLineReservationRequest request,
32+
CancellationToken cancellationToken = default);
33+
}
34+
35+
public class ReservationOperations(ApiClient client) : IReservationOperations
36+
{
37+
readonly ApiClient _client = client;
38+
39+
public async Task<GuestLineResponse<ReservationRef>> ProcessReservationAsync(GuestLineReservationRequest request, CancellationToken cancellationToken = default)
40+
{
41+
42+
Ensure.IsNotNull(request, nameof(request));
43+
44+
request.ApiKey ??= _client.Settings.ApiKey;
45+
request.Version ??= _client.Settings.Version;
46+
47+
request.Validate();
48+
49+
var req = new GuestLineRequest<GuestLineReservationRequest>(
50+
GuestLineService.Reservation,
51+
HttpMethod.Post,
52+
PathString.Empty,
53+
request);
54+
55+
return await _client.FetchAsync<GuestLineReservationRequest, ReservationRef>(req, cancellationToken)
56+
.ConfigureAwait(false);
57+
}
58+
}
59+
60+
public record GuestLineReservationRequest(
61+
[property: JsonPropertyName("propertyid")] string PropertyId,
62+
[property: JsonIgnore] ReservationRequest[] ReservationItems)
63+
: GuestLineRequestBase<GuestLineReservationRequest>("reservation_info")
64+
{
65+
[JsonPropertyName("reservations")]
66+
public GuestLineReservationSet Reservations => new(ReservationItems);
67+
68+
/// <summary>
69+
/// Validates the current instance.
70+
/// </summary>
71+
public override IValidator<GuestLineReservationRequest> GetValidator()
72+
=> GuestLineReservationRequestValidator.Instance;
73+
}
74+
75+
public record GuestLineReservationSet(
76+
[property: JsonPropertyName("reservation")] ReservationRequest[] Reservations);
77+
78+
public class GuestLineReservationRequestValidator : GuestLineRequestBaseValidator<GuestLineReservationRequest>
79+
{
80+
public static readonly GuestLineReservationRequestValidator Instance = new();
81+
82+
public GuestLineReservationRequestValidator()
83+
{
84+
RuleFor(s => s.PropertyId)
85+
.NotEmpty()
86+
.WithMessage("The Property ID parameter must not be empty.");
87+
}
88+
}
89+
90+
public class ReservationRef : Result<ReservationRef>
91+
{
92+
[JsonPropertyName("bookingId")]
93+
public string? BookingId { get; set; }
94+
}
95+
96+
public record ReservationRequest(
97+
[property: JsonPropertyName("reservation_datetime"), JsonConverter(typeof(DateTimeJsonConverter))] DateTime ReservationDateTime,
98+
[property: JsonPropertyName("reservation_id")] string ReservationId,
99+
[property: JsonPropertyName("payment_required")] decimal PaymentRequired,
100+
[property: JsonPropertyName("payment_type")] string PaymentType,
101+
[property: JsonPropertyName("totalamountaftertax")] decimal TotalAmountAfterTax,
102+
[property: JsonPropertyName("totaltax")] decimal TotalTax,
103+
[property: JsonPropertyName("currencycode")] string CurrencyCode,
104+
[property: JsonPropertyName("status")] string Status,
105+
[property: JsonPropertyName("customer")] ReservationCustomer Customer,
106+
[property: JsonPropertyName("room")] ReservationRoom[] Rooms,
107+
[property: JsonPropertyName("POS")] string Source);
108+
109+
public class ReservationCustomer
110+
{
111+
[JsonPropertyName("address")]
112+
public string? Address { get; set; }
113+
114+
[JsonPropertyName("city")]
115+
public string? City { get; set; }
116+
117+
[JsonPropertyName("country")]
118+
public string? Country { get; set; }
119+
120+
[JsonPropertyName("email")]
121+
public string? Email { get; set; }
122+
123+
[JsonPropertyName("salutation")]
124+
public string? Salutation { get; set; }
125+
126+
[JsonPropertyName("first_name")]
127+
public string? FirstName { get; set; }
128+
129+
[JsonPropertyName("last_name")]
130+
public string? LastName { get; set; }
131+
132+
[JsonPropertyName("remarks")]
133+
public string? Remarks { get; set; }
134+
135+
[JsonPropertyName("telephone")]
136+
public string? Telephone { get; set; }
137+
138+
[JsonPropertyName("zip")]
139+
public string? Zip { get; set; }
140+
141+
}
142+
143+
public record ReservationRoom(
144+
[property: JsonPropertyName("arrival_date"), JsonConverter(typeof(DateOnlyJsonConverter))] DateTime ArrivalDate,
145+
[property: JsonPropertyName("departure_date"), JsonConverter(typeof(DateOnlyJsonConverter))] DateTime DepatureDate,
146+
[property: JsonPropertyName("room_id")] string RoomId,
147+
[property: JsonPropertyName("price")] ReservationRate[] Price,
148+
[property: JsonPropertyName("first_name")] string FirstName,
149+
[property: JsonPropertyName("last_name")] string LastName,
150+
[property: JsonPropertyName("remarks")] string? Remarks,
151+
[property: JsonPropertyName("amountaftertax")] decimal AmountAfterTax,
152+
[property: JsonIgnore] int Adults,
153+
[property: JsonIgnore] int Children)
154+
{
155+
[JsonPropertyName("GuestCount")]
156+
public ReservationGuestGrouping[]? Guests => GetGroupings().ToArray();
157+
158+
IEnumerable<ReservationGuestGrouping> GetGroupings()
159+
{
160+
if (Adults > 0)
161+
{
162+
yield return new ReservationGuestGrouping(10, Adults);
163+
}
164+
if (Children > 0)
165+
{
166+
yield return new ReservationGuestGrouping(8, Children);
167+
}
168+
}
169+
}
170+
171+
public record ReservationRate(
172+
[property: JsonPropertyName("date"), JsonConverter(typeof(DateOnlyJsonConverter))] DateTime Date,
173+
[property: JsonPropertyName("rate_id")] string RateId,
174+
[property: JsonPropertyName("amountaftertax")] decimal AmountAfterTax);
175+
176+
public record ReservationGuestGrouping(
177+
[property: JsonPropertyName("AgeQualifyingCode")] int AgeQualifyingCode,
178+
[property: JsonPropertyName("Count")] int Count);

0 commit comments

Comments
 (0)