@v-office/website-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +263 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +337 -0
- package/dist/client-BbAfk-qa.mjs +33672 -0
- package/dist/custom-attribute-ChCbJKf_.mjs +54 -0
- package/dist/errors-2cuUGSvi.mjs +5 -0
- package/dist/index.d.mts +16130 -0
- package/dist/index.mjs +3 -0
- package/dist/operations-BanW36PK.mjs +12616 -0
- package/dist/operations-CHxEQ3jG.mjs +904 -0
- package/dist/parser-D6UAf8Ld.mjs +65 -0
- package/dist/quote-C3HZsFua.mjs +313 -0
- package/dist/quote-Vl6Nutaa.mjs +513 -0
- package/dist/rentals-BFmmp26v.mjs +323 -0
- package/dist/rentals-cQAg5TTW.mjs +403 -0
- package/dist/search-JqA3v_Fx.mjs +342 -0
- package/dist/search-filter-metadata-DZP0-Udc.mjs +4294 -0
- package/dist/to-rental-highlights-BcRa9Odv.mjs +402 -0
- package/dist/translations/shared/de-DE/availability.json +15 -0
- package/dist/translations/shared/de-DE/booking.json +15 -0
- package/dist/translations/shared/de-DE/insurance.json +18 -0
- package/dist/translations/shared/de-DE/quote.json +8 -0
- package/dist/translations/shared/de-DE/reviews.json +11 -0
- package/dist/translations/shared/en-US/availability.json +15 -0
- package/dist/translations/shared/en-US/booking.json +15 -0
- package/dist/translations/shared/en-US/insurance.json +18 -0
- package/dist/translations/shared/en-US/quote.json +8 -0
- package/dist/translations/shared/en-US/reviews.json +11 -0
- package/dist/translations/v10/de-DE/core.json +7027 -0
- package/dist/translations/v10/en-US/core.json +7027 -0
- package/dist/translations/v9/de-DE/core.json +4 -0
- package/dist/translations/v9/de-DE/filter.json +25 -0
- package/dist/translations/v9/de-DE/rental-attribute-categories.json +19 -0
- package/dist/translations/v9/de-DE/rental-attributes.json +451 -0
- package/dist/translations/v9/en-US/core.json +4 -0
- package/dist/translations/v9/en-US/filter.json +25 -0
- package/dist/translations/v9/en-US/rental-attribute-categories.json +19 -0
- package/dist/translations/v9/en-US/rental-attributes.json +451 -0
- package/package.json +90 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import { Qt as formatCurrency, Xt as GuestQuote, Zt as addGuestQuoteAdditionalServiceSelection } from "./client-BbAfk-qa.mjs";
|
|
2
|
+
import "./errors-2cuUGSvi.mjs";
|
|
3
|
+
import { a as toNightCount, c as localeToLanguage } from "./parser-D6UAf8Ld.mjs";
|
|
4
|
+
import { DateTime, Effect } from "effect";
|
|
5
|
+
//#region src/adapters/v10/parser/quote/to-charge.ts
|
|
6
|
+
const toCharge = ({ serviceLine, chargeAmount, currency, locale, translations }) => Effect.gen(function* () {
|
|
7
|
+
switch (serviceLine.serviceLine.calculation) {
|
|
8
|
+
case "FLAT": return formatCurrency(chargeAmount, locale, currency);
|
|
9
|
+
case "NIGHT": return `${formatCurrency(chargeAmount, locale, currency)}${yield* translations.translate(locale, "quote.additionalService.night")}`;
|
|
10
|
+
case "DAY": return `${formatCurrency(chargeAmount, locale, currency)}${yield* translations.translate(locale, "quote.additionalService.day")}`;
|
|
11
|
+
case "USAGE": return formatCurrency(chargeAmount, locale, currency);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/adapters/v10/parser/quote/to-charge-amount.ts
|
|
16
|
+
const toChargeAmount = ({ input, serviceLine }) => {
|
|
17
|
+
const amount = serviceLine.serviceLine.amount ?? 1;
|
|
18
|
+
if (amount <= 0) return void 0;
|
|
19
|
+
switch (serviceLine.serviceLine.calculation) {
|
|
20
|
+
case "FLAT": return serviceLine.total / amount;
|
|
21
|
+
case "NIGHT": return serviceLine.total / toNightCount(input) / amount;
|
|
22
|
+
case "DAY": return serviceLine.total / toNightCount(input) / amount;
|
|
23
|
+
case "USAGE": return serviceLine.total / amount;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/adapters/v10/parser/quote/to-service-line-label.ts
|
|
28
|
+
const toServiceLineLabel = ({ serviceLine, locale, translations }) => Effect.gen(function* () {
|
|
29
|
+
if (serviceLine.serviceLine.service.names != null) return serviceLine.serviceLine.service.names[localeToLanguage(locale)];
|
|
30
|
+
if (serviceLine.serviceLine.service.type !== "OTHER") return yield* translations.translate(locale, `Service.type.${serviceLine.serviceLine.service.type}`);
|
|
31
|
+
return serviceLine.serviceLine.service.label;
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/adapters/v10/parser/quote/utils.ts
|
|
35
|
+
const hasEnoughLeadTime = ({ bookingStart, leadTimeDays, today }) => {
|
|
36
|
+
if (leadTimeDays == null) return true;
|
|
37
|
+
const start = DateTime.removeTime(DateTime.makeUnsafe(bookingStart));
|
|
38
|
+
const earliestStart = DateTime.add(DateTime.removeTime(today), { days: leadTimeDays });
|
|
39
|
+
return DateTime.toEpochMillis(start) >= DateTime.toEpochMillis(earliestStart);
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/adapters/v10/parser/quote/to-additional-services.ts
|
|
43
|
+
const ADDITIONAL_SERVICE_CALCULATION_MAP = {
|
|
44
|
+
FLAT: "FLAT",
|
|
45
|
+
NIGHT: "PER_NIGHT",
|
|
46
|
+
DAY: "PER_DAY",
|
|
47
|
+
USAGE: "PER_USAGE"
|
|
48
|
+
};
|
|
49
|
+
const toAdditionalServices = ({ input, guestQuoteResult, locale, translations }) => Effect.gen(function* () {
|
|
50
|
+
const additionalServices = [];
|
|
51
|
+
const currency = guestQuoteResult?.summary?.currency ?? "EUR";
|
|
52
|
+
const today = yield* DateTime.now;
|
|
53
|
+
for (const line of guestQuoteResult?.lines ?? []) {
|
|
54
|
+
if (!line || line?.mandatory || line?.inSummary) continue;
|
|
55
|
+
if (!hasEnoughLeadTime({
|
|
56
|
+
bookingStart: input.period.start,
|
|
57
|
+
leadTimeDays: line.constraints?.leadTime ?? void 0,
|
|
58
|
+
today
|
|
59
|
+
})) continue;
|
|
60
|
+
const label = yield* toServiceLineLabel({
|
|
61
|
+
serviceLine: line,
|
|
62
|
+
locale,
|
|
63
|
+
translations
|
|
64
|
+
});
|
|
65
|
+
const chargeAmount = toChargeAmount({
|
|
66
|
+
serviceLine: line,
|
|
67
|
+
input
|
|
68
|
+
});
|
|
69
|
+
if (chargeAmount === void 0) continue;
|
|
70
|
+
const charge = yield* toCharge({
|
|
71
|
+
serviceLine: line,
|
|
72
|
+
chargeAmount,
|
|
73
|
+
currency,
|
|
74
|
+
locale,
|
|
75
|
+
translations
|
|
76
|
+
});
|
|
77
|
+
const maxPerBooking = line.constraints?.maxPerBooking ?? void 0;
|
|
78
|
+
const preSelectedQuantity = line.serviceLine.amount == null ? void 0 : Math.min(line.serviceLine.amount, maxPerBooking ?? line.serviceLine.amount);
|
|
79
|
+
additionalServices.push({
|
|
80
|
+
id: line.serviceLine.service.id,
|
|
81
|
+
label,
|
|
82
|
+
charge,
|
|
83
|
+
chargeAmount,
|
|
84
|
+
calculation: ADDITIONAL_SERVICE_CALCULATION_MAP[line.serviceLine.calculation],
|
|
85
|
+
...preSelectedQuantity === void 0 ? {} : { preSelectedQuantity },
|
|
86
|
+
...maxPerBooking === void 0 ? {} : { maxPerBooking },
|
|
87
|
+
...line.constraints?.leadTime == null ? {} : { leadTimeDays: line.constraints.leadTime }
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return additionalServices;
|
|
91
|
+
});
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/adapters/v10/parser/quote/to-backend-context.ts
|
|
94
|
+
const isOptionalServiceLine = (line) => line.mandatory !== true && line.inSummary !== true;
|
|
95
|
+
const toSelectionQuantity = (selections, serviceId) => selections.find((selection) => selection.id === serviceId)?.quantity ?? 0;
|
|
96
|
+
const withSelectedServiceAmounts = (quote, selections) => {
|
|
97
|
+
if (quote?.lines === null || quote?.lines === void 0) return quote;
|
|
98
|
+
return {
|
|
99
|
+
...quote,
|
|
100
|
+
lines: quote.lines.map((line) => {
|
|
101
|
+
if (line === null || !isOptionalServiceLine(line)) return line;
|
|
102
|
+
return {
|
|
103
|
+
...line,
|
|
104
|
+
serviceLine: {
|
|
105
|
+
...line.serviceLine,
|
|
106
|
+
amount: toSelectionQuantity(selections, line.serviceLine.service.id)
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
})
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
const toV10QuoteBackendContext = (input, guestQuoteResult) => ({
|
|
113
|
+
backend: "v10",
|
|
114
|
+
input,
|
|
115
|
+
rawQuote: guestQuoteResult
|
|
116
|
+
});
|
|
117
|
+
const updateV10QuoteBackendContext = (context, selections) => {
|
|
118
|
+
if (context.backend !== "v10") return context;
|
|
119
|
+
return {
|
|
120
|
+
...context,
|
|
121
|
+
rawQuote: withSelectedServiceAmounts(context.rawQuote, selections)
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/adapters/v10/parser/quote/to-cancellation-policies.ts
|
|
126
|
+
const toLocalizedString = (value, locale) => {
|
|
127
|
+
const language = localeToLanguage(locale);
|
|
128
|
+
const localized = value?.[language] ?? value?.en ?? value?.de;
|
|
129
|
+
return localized === void 0 || localized.length === 0 ? void 0 : localized;
|
|
130
|
+
};
|
|
131
|
+
const toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
132
|
+
const toRules = (rules) => {
|
|
133
|
+
const parsedRules = rules.flatMap((rule) => {
|
|
134
|
+
const valuePercentage = toNumber(rule.valuePercentage);
|
|
135
|
+
return valuePercentage === void 0 ? [] : [{
|
|
136
|
+
daysBeforeArrival: rule.daysBeforeArrival,
|
|
137
|
+
valuePercentage
|
|
138
|
+
}];
|
|
139
|
+
});
|
|
140
|
+
return parsedRules.length === 0 ? void 0 : parsedRules;
|
|
141
|
+
};
|
|
142
|
+
const toDefaultPolicyOption = ({ policy, locale }) => {
|
|
143
|
+
const description = toLocalizedString(policy.description, locale);
|
|
144
|
+
const rules = toRules(policy.cancellationRules);
|
|
145
|
+
return {
|
|
146
|
+
id: policy.id,
|
|
147
|
+
kind: "default",
|
|
148
|
+
label: policy.label,
|
|
149
|
+
...description === void 0 ? {} : { description },
|
|
150
|
+
withAlternativeCancellationPolicy: false,
|
|
151
|
+
...rules === void 0 ? {} : { rules }
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
const toCustomPolicyOption = ({ policy, kind, locale }) => {
|
|
155
|
+
const description = toLocalizedString(policy.description, locale);
|
|
156
|
+
const markUpPercentage = toNumber(policy.markUpPercentage);
|
|
157
|
+
const processingFee = toNumber(policy.processingFee);
|
|
158
|
+
const rules = toRules(policy.cancellationRules);
|
|
159
|
+
return {
|
|
160
|
+
id: policy.id,
|
|
161
|
+
kind,
|
|
162
|
+
label: policy.label,
|
|
163
|
+
...description === void 0 ? {} : { description },
|
|
164
|
+
withAlternativeCancellationPolicy: kind === "alternative",
|
|
165
|
+
...markUpPercentage === void 0 ? {} : { markUpPercentage },
|
|
166
|
+
...processingFee === void 0 ? {} : { processingFee },
|
|
167
|
+
...rules === void 0 ? {} : { rules }
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
const toCancellationPolicies = ({ multiRateContextResult, locale }) => {
|
|
171
|
+
const cancellation = multiRateContextResult?.bookings_getCancellation;
|
|
172
|
+
if (cancellation === void 0 || cancellation === null) return [];
|
|
173
|
+
return [cancellation.policyCustom === null ? cancellation.policy === null ? void 0 : toDefaultPolicyOption({
|
|
174
|
+
policy: cancellation.policy,
|
|
175
|
+
locale
|
|
176
|
+
}) : toCustomPolicyOption({
|
|
177
|
+
policy: cancellation.policyCustom,
|
|
178
|
+
kind: "default",
|
|
179
|
+
locale
|
|
180
|
+
}), cancellation.policyAlternative === null ? void 0 : toCustomPolicyOption({
|
|
181
|
+
policy: cancellation.policyAlternative,
|
|
182
|
+
kind: "alternative",
|
|
183
|
+
locale
|
|
184
|
+
})].flatMap((policy) => policy === void 0 ? [] : [policy]);
|
|
185
|
+
};
|
|
186
|
+
const toCancellationPolicySelection = (policy) => policy === void 0 ? void 0 : {
|
|
187
|
+
policyId: policy.id,
|
|
188
|
+
kind: policy.kind,
|
|
189
|
+
withAlternativeCancellationPolicy: policy.withAlternativeCancellationPolicy
|
|
190
|
+
};
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/adapters/v10/parser/quote/to-multi-rate-context.ts
|
|
193
|
+
const V10_MULTI_RATE_INCLUDED_SERVICE_TYPES = new Set([
|
|
194
|
+
"RENT",
|
|
195
|
+
"PET",
|
|
196
|
+
"INTERNET",
|
|
197
|
+
"PRIVAT_PARKING",
|
|
198
|
+
"BREAKFAST",
|
|
199
|
+
"EXTRABED"
|
|
200
|
+
]);
|
|
201
|
+
const toMultiRateContext = (multiRateContextResult) => {
|
|
202
|
+
if (multiRateContextResult === void 0) return void 0;
|
|
203
|
+
return {
|
|
204
|
+
guestRates: multiRateContextResult.bookings_listGuestRate.map((guestRate) => ({
|
|
205
|
+
id: guestRate.id,
|
|
206
|
+
serviceId: guestRate.rate.service.id,
|
|
207
|
+
serviceType: guestRate.rate.serviceType,
|
|
208
|
+
billed: guestRate.rate.billed,
|
|
209
|
+
calculation: guestRate.rate.calculation
|
|
210
|
+
})),
|
|
211
|
+
multiRates: multiRateContextResult.bookings_listMultiRate.map((multiRate) => ({
|
|
212
|
+
id: multiRate.id,
|
|
213
|
+
...multiRate.cancellationPolicy === null ? {} : { cancellationPolicyId: multiRate.cancellationPolicy },
|
|
214
|
+
...multiRate.baseRentRate === null ? {} : { baseRentRate: multiRate.baseRentRate },
|
|
215
|
+
guestRates: (multiRate.guestRates ?? []).flatMap((guestRate) => guestRate.guestRateId === null || guestRate.amount === null ? [] : [{
|
|
216
|
+
guestRateId: guestRate.guestRateId,
|
|
217
|
+
amount: guestRate.amount
|
|
218
|
+
}])
|
|
219
|
+
})),
|
|
220
|
+
includedServiceTypes: V10_MULTI_RATE_INCLUDED_SERVICE_TYPES
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/adapters/v10/parser/quote/to-modifier-label.ts
|
|
225
|
+
const toModifierLabel = ({ input, modifier, locale, translations }) => Effect.gen(function* () {
|
|
226
|
+
if (modifier?.type === "VOUCHER" && input.voucher !== void 0) return (yield* translations.translate(locale, "GuestQuote.modifier.voucher")).replace(" {{code}}", `: ${input.voucher}`);
|
|
227
|
+
const genericKey = `GuestQuote.modifier.generic.${modifier?.type}`;
|
|
228
|
+
const label = yield* translations.translate(locale, genericKey);
|
|
229
|
+
if (label !== genericKey) return label;
|
|
230
|
+
return yield* translations.translate(locale, `GuestQuote.modifier.${modifier?.type}`);
|
|
231
|
+
});
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/adapters/v10/parser/quote/to-modifiers.ts
|
|
234
|
+
const toLineModifiers = ({ input, line, locale, translations }) => Effect.gen(function* () {
|
|
235
|
+
const modifiers = [];
|
|
236
|
+
for (const modifier of line.totalModifiers ?? []) {
|
|
237
|
+
if (!modifier) continue;
|
|
238
|
+
const label = yield* toModifierLabel({
|
|
239
|
+
input,
|
|
240
|
+
modifier,
|
|
241
|
+
locale,
|
|
242
|
+
translations
|
|
243
|
+
});
|
|
244
|
+
modifiers.push({
|
|
245
|
+
label,
|
|
246
|
+
amount: modifier.amount
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
return modifiers;
|
|
250
|
+
});
|
|
251
|
+
const toModifierLines = ({ input, line, locale, translations }) => Effect.gen(function* () {
|
|
252
|
+
const lines = [];
|
|
253
|
+
for (const modifier of line.totalModifiers ?? []) {
|
|
254
|
+
if (!modifier) continue;
|
|
255
|
+
if (modifier.amount >= 0) continue;
|
|
256
|
+
const label = yield* toModifierLabel({
|
|
257
|
+
input,
|
|
258
|
+
modifier,
|
|
259
|
+
locale,
|
|
260
|
+
translations
|
|
261
|
+
});
|
|
262
|
+
lines.push({ item: {
|
|
263
|
+
position: label,
|
|
264
|
+
appliedCharge: modifier.amount
|
|
265
|
+
} });
|
|
266
|
+
}
|
|
267
|
+
return lines;
|
|
268
|
+
});
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/adapters/v10/parser/quote/to-sections-included.ts
|
|
271
|
+
const isIncluded = (line) => line.serviceLine.service.type === "RENT" || line.rateSummary === "SHOW" && line.serviceLine.service.type !== "TAXES";
|
|
272
|
+
const toSectionsIncluded = ({ input, guestQuoteResult, locale, translations }) => Effect.gen(function* () {
|
|
273
|
+
const subItems = [];
|
|
274
|
+
const modifiers = [];
|
|
275
|
+
let total = 0;
|
|
276
|
+
for (const line of guestQuoteResult?.lines ?? []) {
|
|
277
|
+
if (!line) continue;
|
|
278
|
+
if (isIncluded(line)) {
|
|
279
|
+
total += line.total;
|
|
280
|
+
modifiers.push(...yield* toLineModifiers({
|
|
281
|
+
input,
|
|
282
|
+
line,
|
|
283
|
+
locale,
|
|
284
|
+
translations
|
|
285
|
+
}));
|
|
286
|
+
const position = yield* toServiceLineLabel({
|
|
287
|
+
serviceLine: line,
|
|
288
|
+
locale,
|
|
289
|
+
translations
|
|
290
|
+
});
|
|
291
|
+
subItems.push({
|
|
292
|
+
position,
|
|
293
|
+
appliedCharge: yield* translations.translate(locale, "quote.sections.included")
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
if (line.rateSummary === "ADD_NO_SHOW" && line.serviceLine.service.type !== "TAXES") {
|
|
297
|
+
total += line.total;
|
|
298
|
+
modifiers.push(...yield* toLineModifiers({
|
|
299
|
+
input,
|
|
300
|
+
line,
|
|
301
|
+
locale,
|
|
302
|
+
translations
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
item: {
|
|
308
|
+
position: yield* translations.translate(locale, "quote.sections.inclusivePrice"),
|
|
309
|
+
appliedCharge: total,
|
|
310
|
+
...modifiers.length === 0 ? {} : { modifiers }
|
|
311
|
+
},
|
|
312
|
+
subItems
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/adapters/v10/parser/quote/to-sections-other.ts
|
|
317
|
+
const isOther = (line) => line.serviceLine.service.type !== "RENT" && line.serviceLine.service.type !== "TAXES" && line.mandatory === true && line.inSummary === false;
|
|
318
|
+
const toSectionsOther = ({ input, guestQuoteResult, locale, translations }) => Effect.gen(function* () {
|
|
319
|
+
const lines = [];
|
|
320
|
+
for (const line of guestQuoteResult?.lines ?? []) {
|
|
321
|
+
if (!line) continue;
|
|
322
|
+
if (isOther(line)) {
|
|
323
|
+
const position = yield* toServiceLineLabel({
|
|
324
|
+
serviceLine: line,
|
|
325
|
+
locale,
|
|
326
|
+
translations
|
|
327
|
+
});
|
|
328
|
+
const modifiers = yield* toLineModifiers({
|
|
329
|
+
input,
|
|
330
|
+
line,
|
|
331
|
+
locale,
|
|
332
|
+
translations
|
|
333
|
+
});
|
|
334
|
+
lines.push({ item: {
|
|
335
|
+
position,
|
|
336
|
+
appliedCharge: line.total,
|
|
337
|
+
...modifiers.length === 0 ? {} : { modifiers }
|
|
338
|
+
} });
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return lines;
|
|
342
|
+
});
|
|
343
|
+
//#endregion
|
|
344
|
+
//#region src/adapters/v10/parser/quote/to-sections-tax.ts
|
|
345
|
+
const isTax = (line) => line.serviceLine.service.type === "TAXES";
|
|
346
|
+
const toSectionsTax = ({ input, guestQuoteResult, locale, translations }) => Effect.gen(function* () {
|
|
347
|
+
const subItems = [];
|
|
348
|
+
const modifiers = [];
|
|
349
|
+
let total = 0;
|
|
350
|
+
for (const line of guestQuoteResult?.lines ?? []) {
|
|
351
|
+
if (!line) continue;
|
|
352
|
+
if (isTax(line)) {
|
|
353
|
+
total += line.total;
|
|
354
|
+
modifiers.push(...yield* toLineModifiers({
|
|
355
|
+
input,
|
|
356
|
+
line,
|
|
357
|
+
locale,
|
|
358
|
+
translations
|
|
359
|
+
}));
|
|
360
|
+
const position = yield* toServiceLineLabel({
|
|
361
|
+
serviceLine: line,
|
|
362
|
+
locale,
|
|
363
|
+
translations
|
|
364
|
+
});
|
|
365
|
+
subItems.push({
|
|
366
|
+
position: line.serviceLine.service.label ?? position,
|
|
367
|
+
appliedCharge: yield* translations.translate(locale, "quote.sections.included")
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return { item: {
|
|
372
|
+
position: yield* translations.translate(locale, "quote.sections.tax"),
|
|
373
|
+
appliedCharge: total,
|
|
374
|
+
...modifiers.length === 0 ? {} : { modifiers }
|
|
375
|
+
} };
|
|
376
|
+
});
|
|
377
|
+
//#endregion
|
|
378
|
+
//#region src/adapters/v10/parser/quote/to-sections.ts
|
|
379
|
+
const hasSectionLineContent = (line) => line.item.appliedCharge !== 0 || (line.subItems?.length ?? 0) > 0;
|
|
380
|
+
const isIncludedSectionLine = (line) => line.serviceLine.service.type === "RENT" || line.rateSummary === "SHOW" && line.serviceLine.service.type !== "TAXES" || line.rateSummary === "ADD_NO_SHOW" && line.serviceLine.service.type !== "TAXES";
|
|
381
|
+
const isTaxSectionLine = (line) => line.serviceLine.service.type === "TAXES";
|
|
382
|
+
const isOtherSectionLine = (line) => line.serviceLine.service.type !== "RENT" && line.serviceLine.service.type !== "TAXES" && line.mandatory === true && line.inSummary === false;
|
|
383
|
+
const toSections = ({ input, guestQuoteResult, locale, translations }) => Effect.gen(function* () {
|
|
384
|
+
const sections = [];
|
|
385
|
+
const sectionsIncluded = yield* toSectionsIncluded({
|
|
386
|
+
input,
|
|
387
|
+
guestQuoteResult,
|
|
388
|
+
locale,
|
|
389
|
+
translations
|
|
390
|
+
});
|
|
391
|
+
const sectionsTax = yield* toSectionsTax({
|
|
392
|
+
input,
|
|
393
|
+
guestQuoteResult,
|
|
394
|
+
locale,
|
|
395
|
+
translations
|
|
396
|
+
});
|
|
397
|
+
const sectionsOther = yield* toSectionsOther({
|
|
398
|
+
input,
|
|
399
|
+
guestQuoteResult,
|
|
400
|
+
locale,
|
|
401
|
+
translations
|
|
402
|
+
});
|
|
403
|
+
const unmappedModifierLines = [];
|
|
404
|
+
for (const line of guestQuoteResult?.lines ?? []) {
|
|
405
|
+
if (!line) continue;
|
|
406
|
+
if ((line.totalModifiers ?? []).length === 0) continue;
|
|
407
|
+
if (isIncludedSectionLine(line) || isTaxSectionLine(line) || isOtherSectionLine(line)) continue;
|
|
408
|
+
unmappedModifierLines.push(...yield* toModifierLines({
|
|
409
|
+
input,
|
|
410
|
+
line,
|
|
411
|
+
locale,
|
|
412
|
+
translations
|
|
413
|
+
}));
|
|
414
|
+
}
|
|
415
|
+
if (hasSectionLineContent(sectionsIncluded)) sections.push({ lines: [sectionsIncluded] });
|
|
416
|
+
if (hasSectionLineContent(sectionsTax)) sections.push({ lines: [sectionsTax] });
|
|
417
|
+
if (sectionsOther.length > 0) sections.push({ lines: sectionsOther });
|
|
418
|
+
if (unmappedModifierLines.length > 0) sections.push({ lines: unmappedModifierLines });
|
|
419
|
+
return sections;
|
|
420
|
+
});
|
|
421
|
+
//#endregion
|
|
422
|
+
//#region src/adapters/v10/parser/quote/to-guest-quote.ts
|
|
423
|
+
const hasPriceSummary = (guestQuoteResult) => guestQuoteResult !== null && guestQuoteResult.summary !== null;
|
|
424
|
+
const toWarningCodes = (guestQuoteResult) => (guestQuoteResult?.warnings ?? []).filter((warning) => warning !== null && warning.trim().length > 0);
|
|
425
|
+
const toUnavailableReason = (guestQuoteResult, locale, translations) => Effect.gen(function* () {
|
|
426
|
+
const warningCodes = toWarningCodes(guestQuoteResult);
|
|
427
|
+
if (warningCodes.length > 0) return (yield* Effect.all(warningCodes.map((warningCode) => translations.translate(locale, `Quote.warnings.${warningCode}`, warningCode)))).join("\n");
|
|
428
|
+
return yield* translations.translate(locale, "quote.status.unavailable.notBookable", "Not available");
|
|
429
|
+
});
|
|
430
|
+
const toGuestQuoteVariant = ({ input, guestQuoteResult, policyId, locale, translations }) => Effect.gen(function* () {
|
|
431
|
+
const summary = guestQuoteResult.summary;
|
|
432
|
+
const sections = yield* toSections({
|
|
433
|
+
input,
|
|
434
|
+
guestQuoteResult,
|
|
435
|
+
locale,
|
|
436
|
+
translations
|
|
437
|
+
});
|
|
438
|
+
const additionalServices = yield* toAdditionalServices({
|
|
439
|
+
input,
|
|
440
|
+
guestQuoteResult,
|
|
441
|
+
locale,
|
|
442
|
+
translations
|
|
443
|
+
});
|
|
444
|
+
return {
|
|
445
|
+
policyId,
|
|
446
|
+
bookingCardInformation: {
|
|
447
|
+
sections,
|
|
448
|
+
total: summary.total
|
|
449
|
+
},
|
|
450
|
+
baseTotal: summary.total,
|
|
451
|
+
currency: summary.currency,
|
|
452
|
+
additionalServices,
|
|
453
|
+
backendContext: toV10QuoteBackendContext(input, guestQuoteResult)
|
|
454
|
+
};
|
|
455
|
+
});
|
|
456
|
+
const toGuestQuote = (input, guestQuoteResult, locale, translations, options) => Effect.gen(function* () {
|
|
457
|
+
if (!hasPriceSummary(guestQuoteResult)) return {
|
|
458
|
+
status: "unavailable",
|
|
459
|
+
reason: yield* toUnavailableReason(guestQuoteResult, locale, translations)
|
|
460
|
+
};
|
|
461
|
+
const cancellationPolicies = toCancellationPolicies({
|
|
462
|
+
multiRateContextResult: options?.multiRateContextResult,
|
|
463
|
+
locale
|
|
464
|
+
});
|
|
465
|
+
const defaultPolicy = cancellationPolicies.find((policy) => policy.kind === "default");
|
|
466
|
+
const alternativePolicy = cancellationPolicies.find((policy) => policy.kind === "alternative");
|
|
467
|
+
const multiRateContext = toMultiRateContext(options?.multiRateContextResult);
|
|
468
|
+
const defaultVariant = yield* toGuestQuoteVariant({
|
|
469
|
+
input,
|
|
470
|
+
guestQuoteResult,
|
|
471
|
+
policyId: defaultPolicy?.id ?? "default",
|
|
472
|
+
locale,
|
|
473
|
+
translations
|
|
474
|
+
});
|
|
475
|
+
const alternativeVariant = alternativePolicy === void 0 || options?.alternativeGuestQuoteResult === void 0 || !hasPriceSummary(options.alternativeGuestQuoteResult) ? void 0 : yield* toGuestQuoteVariant({
|
|
476
|
+
input,
|
|
477
|
+
guestQuoteResult: options.alternativeGuestQuoteResult,
|
|
478
|
+
policyId: alternativePolicy.id,
|
|
479
|
+
locale,
|
|
480
|
+
translations
|
|
481
|
+
});
|
|
482
|
+
const cancellationPolicyQuoteVariants = cancellationPolicies.length === 0 ? [] : [defaultVariant, alternativeVariant].flatMap((variant) => variant === void 0 ? [] : [variant]);
|
|
483
|
+
const cancellationPolicySelection = toCancellationPolicySelection(defaultPolicy);
|
|
484
|
+
let guestQuote = new GuestQuote({
|
|
485
|
+
input,
|
|
486
|
+
bookingCardInformation: defaultVariant.bookingCardInformation,
|
|
487
|
+
baseTotal: defaultVariant.baseTotal,
|
|
488
|
+
currency: defaultVariant.currency,
|
|
489
|
+
additionalServices: defaultVariant.additionalServices,
|
|
490
|
+
updateBackendContext: updateV10QuoteBackendContext,
|
|
491
|
+
cancellationPolicies,
|
|
492
|
+
cancellationPolicyQuoteVariants,
|
|
493
|
+
...defaultVariant.backendContext === void 0 ? {} : { backendContext: defaultVariant.backendContext },
|
|
494
|
+
...cancellationPolicySelection === void 0 ? {} : { cancellationPolicySelection },
|
|
495
|
+
...multiRateContext === void 0 ? {} : { multiRateContext }
|
|
496
|
+
});
|
|
497
|
+
for (const additionalService of defaultVariant.additionalServices) {
|
|
498
|
+
if (additionalService.preSelectedQuantity === void 0) continue;
|
|
499
|
+
for (let quantity = 0; quantity < additionalService.preSelectedQuantity; quantity++) {
|
|
500
|
+
const result = addGuestQuoteAdditionalServiceSelection({
|
|
501
|
+
quote: guestQuote,
|
|
502
|
+
id: additionalService.id
|
|
503
|
+
});
|
|
504
|
+
if (result.ok) guestQuote = result.quote;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
status: "available",
|
|
509
|
+
quote: guestQuote
|
|
510
|
+
};
|
|
511
|
+
});
|
|
512
|
+
//#endregion
|
|
513
|
+
export { toAdditionalServices, toGuestQuote };
|