@wix/headless-bookings 1.0.0 → 1.0.2

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.
Files changed (37) hide show
  1. package/cjs/dist/__mocks__/booking/booking-mocks.d.ts +1 -1
  2. package/cjs/dist/__mocks__/services/services-mocks.d.ts +23 -0
  3. package/cjs/dist/__mocks__/services/services-mocks.js +65 -1
  4. package/cjs/dist/api/query-services/index.js +2 -2
  5. package/cjs/dist/react/core/booking/Booking.d.ts +1 -1
  6. package/cjs/dist/react/core/booking/Booking.js +18 -5
  7. package/cjs/dist/react/core/location/Location.d.ts +1 -1
  8. package/cjs/dist/react/core/location/Location.js +5 -5
  9. package/cjs/dist/react/core/service/Service.d.ts +10 -1
  10. package/cjs/dist/react/core/service/Service.js +5 -4
  11. package/cjs/dist/react/service/Service.d.ts +68 -1
  12. package/cjs/dist/react/service/Service.js +81 -1
  13. package/cjs/dist/services/booking/booking.d.ts +1 -1
  14. package/cjs/dist/services/location-list/location-list.def.d.ts +1 -1
  15. package/cjs/dist/services/location-list/location-list.def.js +1 -1
  16. package/cjs/dist/services/location-list/location-list.js +7 -7
  17. package/cjs/dist/services/payment/payment.def.d.ts +6 -0
  18. package/cjs/dist/services/payment/payment.js +56 -5
  19. package/dist/__mocks__/booking/booking-mocks.d.ts +1 -1
  20. package/dist/__mocks__/services/services-mocks.d.ts +23 -0
  21. package/dist/__mocks__/services/services-mocks.js +64 -0
  22. package/dist/api/query-services/index.js +1 -1
  23. package/dist/react/core/booking/Booking.d.ts +1 -1
  24. package/dist/react/core/booking/Booking.js +18 -5
  25. package/dist/react/core/location/Location.d.ts +1 -1
  26. package/dist/react/core/location/Location.js +1 -1
  27. package/dist/react/core/service/Service.d.ts +10 -1
  28. package/dist/react/core/service/Service.js +5 -4
  29. package/dist/react/service/Service.d.ts +68 -1
  30. package/dist/react/service/Service.js +81 -1
  31. package/dist/services/booking/booking.d.ts +1 -1
  32. package/dist/services/location-list/location-list.def.d.ts +1 -1
  33. package/dist/services/location-list/location-list.def.js +1 -1
  34. package/dist/services/location-list/location-list.js +1 -1
  35. package/dist/services/payment/payment.def.d.ts +6 -0
  36. package/dist/services/payment/payment.js +57 -6
  37. package/package.json +5 -3
@@ -6,8 +6,9 @@
6
6
  import { implementService } from '@wix/services-definitions';
7
7
  import { SignalsServiceDefinition } from '@wix/services-definitions/core-services/signals';
8
8
  import { calculateTotals, } from '@wix/auto_sdk_ecom_totals-calculator';
9
+ import { previewPrice, } from '@wix/auto_sdk_bookings_pricing';
9
10
  import { BookingServiceDefinition } from '../booking/booking.js';
10
- import { RateType } from '@wix/auto_sdk_bookings_services';
11
+ import { RateType, } from '@wix/auto_sdk_bookings_services';
11
12
  import { PaymentServiceDefinition, } from './payment.def.js';
12
13
  import { generateLineItemId } from '../../utils/guid.js';
13
14
  export { PaymentServiceDefinition, } from './payment.def.js';
@@ -86,13 +87,56 @@ function buildLineItem(service, totalParticipants, lineItemId) {
86
87
  paymentOption,
87
88
  };
88
89
  }
90
+ // durationRange is an @internal field on AvailabilityConstraints (bookings services SDK v1.0.226+).
91
+ // It signals that the service uses flexible duration pricing (hourly/daily rentals),
92
+ // where the correct price must be fetched via previewPrice() rather than the fixed unit price.
93
+ function getDurationRange(service) {
94
+ return service.schedule?.availabilityConstraints?.durationRange;
95
+ }
96
+ async function getPreviewedPrice(service, localStartDate, localEndDate, timeZone) {
97
+ if (!service._id)
98
+ return null;
99
+ const lineItemInput = {
100
+ serviceId: service._id,
101
+ localStartDate,
102
+ localEndDate,
103
+ ...(timeZone ? { timeZone } : {}),
104
+ };
105
+ const result = await previewPrice([lineItemInput]);
106
+ return result.priceInfo?.calculatedPrice ?? null;
107
+ }
108
+ async function buildLineItemWithPreview(item, totalParticipants) {
109
+ if (item.localStartDate &&
110
+ item.localEndDate &&
111
+ getDurationRange(item.service)) {
112
+ const previewedPrice = await getPreviewedPrice(item.service, item.localStartDate, item.localEndDate, item.timeZone).catch(() => null);
113
+ if (previewedPrice != null) {
114
+ const depositValue = item.service.payment?.fixed?.deposit?.value;
115
+ const hasDeposit = !!depositValue && Number(depositValue) > 0;
116
+ const deposit = hasDeposit
117
+ ? Number(depositValue) * totalParticipants
118
+ : undefined;
119
+ return {
120
+ _id: item.lineItemId,
121
+ catalogReference: {
122
+ catalogItemId: item.service._id || '',
123
+ appId: BOOKING_APP_ID,
124
+ },
125
+ price: String(previewedPrice),
126
+ ...(deposit ? { depositAmount: String(deposit) } : {}),
127
+ quantity: 1,
128
+ paymentOption: getPaymentOption(item.service, hasDeposit),
129
+ };
130
+ }
131
+ }
132
+ return buildLineItem(item.service, totalParticipants, item.lineItemId);
133
+ }
89
134
  async function calculatePaymentDetails(pricingServiceSelections, totalParticipants) {
90
- // Ensure all booking services have a lineItemId
91
135
  const data = pricingServiceSelections.map((selection) => ({
92
136
  ...selection,
93
137
  lineItemId: selection.lineItemId || generateLineItemId(),
94
138
  }));
95
- const lineItems = data.map((item) => buildLineItem(item.service, totalParticipants, item.lineItemId));
139
+ const lineItems = await Promise.all(data.map((item) => buildLineItemWithPreview(item, totalParticipants)));
96
140
  const response = await calculateTotals({
97
141
  lineItems,
98
142
  });
@@ -163,22 +207,29 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
163
207
  }
164
208
  // Mode 3: Reactive - observe BookingService signals (client-side only)
165
209
  else if (typeof window !== 'undefined' && bookingService) {
166
- // Computed signal that only changes when services change (not participants)
210
+ // Computed signal that changes when services or selected time slots change (not participants)
167
211
  const servicesKey = signalsService.computed(() => {
168
212
  const selections = bookingService?.serviceSelections.get() || [];
169
- return selections.map((s) => s.service._id).join(',');
213
+ const timezone = bookingService?.timezone.get();
214
+ return (selections
215
+ .map((s) => `${s.service._id}:${s.timeSlot?.startDate ?? ''}:${s.timeSlot?.endDate ?? ''}`)
216
+ .join(',') + `:${timezone ?? ''}`);
170
217
  });
171
218
  signalsService.effect(() => {
172
- // Subscribe to servicesKey to trigger effect only when services change
219
+ // Subscribe to servicesKey to trigger effect when service or time slot changes
173
220
  servicesKey.get();
174
221
  // Read current selections without subscribing (peek)
175
222
  const selections = bookingService?.serviceSelections.peek() || [];
223
+ const timezone = bookingService?.timezone.peek();
176
224
  // For single service mode, take the first selection
177
225
  const firstSelection = selections[0];
178
226
  const numParticipants = firstSelection?.totalParticipants || 1;
179
227
  const pricingServiceSelections = selections.map((selection) => ({
180
228
  service: selection.service,
181
229
  lineItemId: selection.instanceId,
230
+ localStartDate: selection.timeSlot?.startDate,
231
+ localEndDate: selection.timeSlot?.endDate,
232
+ timeZone: timezone,
182
233
  }));
183
234
  if (pricingServiceSelections.length) {
184
235
  serviceOptionsSignal.set(deriveServiceOptions(pricingServiceSelections));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/headless-bookings",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -34,8 +34,10 @@
34
34
  }
35
35
  },
36
36
  "dependencies": {
37
- "@wix/auto_sdk_bookings_bookings": "^1.0.103",
37
+ "@wix/auto_sdk_bookings_bookings": "^1.0.183",
38
38
  "@wix/auto_sdk_bookings_event-time-slots": "^1.0.64",
39
+ "@wix/auto_sdk_bookings_pricing": "^1.0.87",
40
+ "@wix/auto_sdk_bookings_services": "^1.0.226",
39
41
  "@wix/auto_sdk_ecom_cart-v-2": "^1.0.86",
40
42
  "@wix/forms": "^1.0.384",
41
43
  "@wix/headless-media": "0.0.25",
@@ -73,5 +75,5 @@
73
75
  "groupId": "com.wixpress.headless-components"
74
76
  }
75
77
  },
76
- "falconPackageHash": "c937e3d58e53147f0712bea70a6759a841fd018967a90028599b0895"
78
+ "falconPackageHash": "402687344b7c916e00531f83dab622fae9b9efda7b82abadc49c484b"
77
79
  }