@nuxt-customer-portal/planning 0.7.0 → 0.8.1
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @nuxt-customer-portal/products@0.8.1
|
|
9
|
+
- @nuxt-customer-portal/core@0.8.1
|
|
10
|
+
- @nuxt-customer-portal/ui@0.8.1
|
|
11
|
+
|
|
12
|
+
## 0.8.0
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- e558791: Support store-wide online and deferred invoice payment choices with immediate purchase fulfillment, linked unsent invoice drafts, inclusive tax review, and manual payment progress. Add unlisted products with server-generated unguessable slugs, excluded from catalog discovery while remaining available through individual product pages.
|
|
17
|
+
- Updated dependencies [175854d]
|
|
18
|
+
- Updated dependencies [e558791]
|
|
19
|
+
- Updated dependencies [28bb7af]
|
|
20
|
+
- @nuxt-customer-portal/core@0.8.0
|
|
21
|
+
- @nuxt-customer-portal/ui@0.8.0
|
|
22
|
+
- @nuxt-customer-portal/products@0.8.0
|
|
23
|
+
|
|
3
24
|
## 0.7.0
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -3,6 +3,8 @@ import type { HoldResult } from '../../composables/usePlanning'
|
|
|
3
3
|
import { resolveCheckoutQuery, resolveCheckoutReturnUrl } from '@nuxt-customer-portal/products/shared/checkout-query'
|
|
4
4
|
import { formatMoney } from '@nuxt-customer-portal/products/shared/money'
|
|
5
5
|
|
|
6
|
+
useHead({ meta: [{ name: 'robots', content: 'noindex, nofollow' }] })
|
|
7
|
+
|
|
6
8
|
definePageMeta({ path: '/store/:slug/book', public: true, layout: 'store', key: (route) => `booking:${route.path}` })
|
|
7
9
|
const route = useRoute(),
|
|
8
10
|
{ t, locale, setLocale } = useI18n(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxt-customer-portal/planning",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://nuxt-customer-portal.com",
|
|
6
6
|
"repository": {
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"drizzle-orm": "^0.45.2",
|
|
41
41
|
"pg": "^8.22.0",
|
|
42
42
|
"zod": "^4.4.3",
|
|
43
|
-
"@nuxt-customer-portal/core": "^0.
|
|
44
|
-
"@nuxt-customer-portal/
|
|
45
|
-
"@nuxt-customer-portal/
|
|
43
|
+
"@nuxt-customer-portal/core": "^0.8.1",
|
|
44
|
+
"@nuxt-customer-portal/products": "^0.8.1",
|
|
45
|
+
"@nuxt-customer-portal/ui": "^0.8.1"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"nuxt": "^4.5.1",
|
package/portal.manifest.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { rows } from '@nuxt-customer-portal/products/server/utils/database'
|
|
|
5
5
|
export default defineEventHandler(async (event) => {
|
|
6
6
|
const scope = await appointmentScope(event)
|
|
7
7
|
return rows(
|
|
8
|
-
`SELECT slug,COALESCE(NULLIF(data->'content'->'en'->>'title',''),data->'content'->'nl'->>'title') AS title FROM products.product WHERE store_id=$1 AND data->>'status'='published' AND data->>'type'='service' AND data->'planning'->>'enabled'='true' ORDER BY title,id`,
|
|
8
|
+
`SELECT slug,COALESCE(NULLIF(data->'content'->'en'->>'title',''),data->'content'->'nl'->>'title') AS title FROM products.product WHERE store_id=$1 AND data->>'status'='published' AND COALESCE(data->>'visibility','listed')='listed' AND data->>'type'='service' AND data->'planning'->>'enabled'='true' ORDER BY title,id`,
|
|
9
9
|
[scope.storeId]
|
|
10
10
|
)
|
|
11
11
|
})
|
package/server/utils/booking.ts
CHANGED
|
@@ -485,8 +485,8 @@ export async function prepareOrder(order: Order) {
|
|
|
485
485
|
let failure: string | undefined
|
|
486
486
|
if (
|
|
487
487
|
hold.status !== 'reserved' ||
|
|
488
|
-
!order.snapshot.paymentCompletedAt ||
|
|
489
|
-
Date.parse(order.snapshot.paymentCompletedAt) > hold.expires_at.getTime()
|
|
488
|
+
!(order.snapshot.acceptedAt || order.snapshot.paymentCompletedAt) ||
|
|
489
|
+
Date.parse((order.snapshot.acceptedAt || order.snapshot.paymentCompletedAt)!) > hold.expires_at.getTime()
|
|
490
490
|
) {
|
|
491
491
|
failure = 'Reservation expired before payment completed'
|
|
492
492
|
} else {
|
|
@@ -544,8 +544,8 @@ export async function confirm(tx: PoolClient, order: Order) {
|
|
|
544
544
|
if (
|
|
545
545
|
order.snapshot.planningFailure ||
|
|
546
546
|
hold.status !== 'reserved' ||
|
|
547
|
-
!order.snapshot.paymentCompletedAt ||
|
|
548
|
-
Date.parse(order.snapshot.paymentCompletedAt) > hold.expires_at.getTime()
|
|
547
|
+
!(order.snapshot.acceptedAt || order.snapshot.paymentCompletedAt) ||
|
|
548
|
+
Date.parse((order.snapshot.acceptedAt || order.snapshot.paymentCompletedAt)!) > hold.expires_at.getTime()
|
|
549
549
|
) {
|
|
550
550
|
await tx.query(
|
|
551
551
|
"UPDATE products.orders SET snapshot=jsonb_set(snapshot,'{planningFailure}',to_jsonb($2::text)) WHERE id=$1",
|
package/server/utils/jobs.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { orderDownloadToken, purchaseDownloads } from '@nuxt-customer-portal/products/server/utils/downloads'
|
|
2
|
+
import { downloadEmailMarkdown } from '@nuxt-customer-portal/products/shared/downloads'
|
|
1
3
|
import { randomUUID } from 'node:crypto'
|
|
2
4
|
import { pool } from '@nuxt-customer-portal/core/server/utils/db'
|
|
3
5
|
import { sendPortalEmail } from '@nuxt-customer-portal/core/server/utils/portal-email'
|
|
@@ -181,7 +183,19 @@ async function appointmentEffects(
|
|
|
181
183
|
timezone: a.snapshot.customerTimezone,
|
|
182
184
|
meetingUrl: a.meeting_url || appointmentUrl,
|
|
183
185
|
meetingDetails,
|
|
184
|
-
instructions:
|
|
186
|
+
instructions: [
|
|
187
|
+
order.lines[0]!.snapshot.product.nextSteps[locale] || '',
|
|
188
|
+
order.snapshot.paymentMethod === 'invoice' && a.status !== 'cancelled'
|
|
189
|
+
? locale === 'nl'
|
|
190
|
+
? 'Je ontvangt de factuur later apart.'
|
|
191
|
+
: 'Your invoice will follow separately.'
|
|
192
|
+
: '',
|
|
193
|
+
a.status === 'cancelled'
|
|
194
|
+
? ''
|
|
195
|
+
: downloadEmailMarkdown(await purchaseDownloads(order, await orderDownloadToken(order.id)), locale)
|
|
196
|
+
]
|
|
197
|
+
.filter(Boolean)
|
|
198
|
+
.join('\n\n'),
|
|
185
199
|
url: appointmentUrl
|
|
186
200
|
}
|
|
187
201
|
const invitation = calendarInvitation({
|
|
@@ -584,7 +598,7 @@ export async function expireReservations() {
|
|
|
584
598
|
await reconcileCheckout(order.checkout_id)
|
|
585
599
|
}
|
|
586
600
|
const current = await getOrder(hold.order_id)
|
|
587
|
-
if (current
|
|
601
|
+
if (current && ['paid', 'accepted'].includes(current.status)) {
|
|
588
602
|
await processOrder(current.id)
|
|
589
603
|
continue
|
|
590
604
|
}
|
|
@@ -383,7 +383,7 @@ export async function abandonChange(event: H3Event, id: string) {
|
|
|
383
383
|
[hold.order_id],
|
|
384
384
|
tx
|
|
385
385
|
)
|
|
386
|
-
if (order
|
|
386
|
+
if (order && ['paid', 'accepted'].includes(order.status)) {
|
|
387
387
|
return
|
|
388
388
|
}
|
|
389
389
|
await tx.query("UPDATE products.orders SET status='expired' WHERE id=$1 AND status='pending'", [hold.order_id])
|