@licklist/design 0.71.18-dev.1 → 0.71.18-dev.11
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/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.js +1 -0
- package/dist/events/event-statistic-modal/utils/index.js +3 -3
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.d.ts +18 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.js +295 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.d.ts +15 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.js +89 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.d.ts +14 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.js +404 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.d.ts +10 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.js +87 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/index.d.ts +2 -0
- package/dist/iframe/ProductWithModifierModal/ModifierSetModal/index.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/index.d.ts +2 -0
- package/dist/iframe/ProductWithModifierModal/index.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/utils.d.ts +5 -0
- package/dist/iframe/ProductWithModifierModal/utils.d.ts.map +1 -0
- package/dist/iframe/ProductWithModifierModal/utils.js +21 -0
- package/dist/iframe/activity-card/ActivityCard.d.ts +1 -2
- package/dist/iframe/activity-card/ActivityCard.d.ts.map +1 -1
- package/dist/iframe/activity-card/ActivityCard.js +1 -7
- package/dist/iframe/event/ticket-description/TicketDescription.d.ts +2 -1
- package/dist/iframe/event/ticket-description/TicketDescription.d.ts.map +1 -1
- package/dist/iframe/event/ticket-description/TicketDescription.js +4 -3
- package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts +1 -1
- package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts.map +1 -1
- package/dist/iframe/order-process/components/BookingSummary/BookingSummary.js +2 -1
- package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.d.ts.map +1 -1
- package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.js +15 -2
- package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts +1 -0
- package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts.map +1 -1
- package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts +4 -0
- package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts.map +1 -1
- package/dist/iframe/order-process/components/BookingSummary/utils/index.js +29 -2
- package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.d.ts.map +1 -1
- package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.js +106 -2
- package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts +3 -1
- package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts.map +1 -1
- package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.js +95 -1
- package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.d.ts +23 -0
- package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.d.ts.map +1 -0
- package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.js +62 -0
- package/dist/iframe/order-process/components/CategoryProduct/constants.d.ts +2 -0
- package/dist/iframe/order-process/components/CategoryProduct/constants.d.ts.map +1 -0
- package/dist/iframe/order-process/components/CategoryProduct/constants.js +4 -0
- package/dist/iframe/order-process/components/utils/useOnWindowUnmount.d.ts +6 -0
- package/dist/iframe/order-process/components/utils/useOnWindowUnmount.d.ts.map +1 -0
- package/dist/iframe/order-process/components/utils/useOnWindowUnmount.js +18 -0
- package/dist/iframe/payment/order-items-table/hooks/useTableData.d.ts.map +1 -1
- package/dist/iframe/payment/order-items-table/hooks/useTableData.js +83 -10
- package/dist/iframe/payment/order-items-table/utils/index.d.ts.map +1 -1
- package/dist/iframe/payment/order-items-table/utils/index.js +15 -0
- package/dist/iframe/payment/order-items-table/utils/paymentSummary.js +2 -2
- package/dist/iframe/payment/payment-page/PaymentPage.d.ts.map +1 -1
- package/dist/iframe/payment/payment-page/PaymentPage.js +4 -1
- package/dist/index.js +1 -1
- package/dist/product-set/form/ProductSetForm.d.ts +3 -1
- package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
- package/dist/product-set/form/ProductSetForm.js +6 -4
- package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
- package/dist/product-set/form/ProductsControl.js +24 -5
- package/dist/product-set/form/context.d.ts +3 -1
- package/dist/product-set/form/context.d.ts.map +1 -1
- package/dist/product-set/form/context.js +2 -1
- package/dist/product-set/product/ProductControl.d.ts +8 -0
- package/dist/product-set/product/ProductControl.d.ts.map +1 -1
- package/dist/product-set/product/ProductControl.js +25 -1
- package/dist/product-set/utils/index.d.ts +88 -0
- package/dist/product-set/utils/index.d.ts.map +1 -1
- package/dist/product-set/utils/index.js +19 -1
- package/dist/report/ReportRunnerModal/ReportRunnerModal.d.ts +1 -1
- package/dist/report/ReportRunnerModal/ReportRunnerModal.d.ts.map +1 -1
- package/dist/sales/coupon/utils/index.d.ts +2 -1
- package/dist/sales/coupon/utils/index.d.ts.map +1 -1
- package/dist/sales/modals/refund-modal/RefundModal.d.ts +6 -2
- package/dist/sales/modals/refund-modal/RefundModal.d.ts.map +1 -1
- package/dist/sales/modals/refund-modal/RefundModal.js +8 -4
- package/dist/sales/modals/refund-modal/index.d.ts +2 -2
- package/dist/sales/modals/refund-modal/index.d.ts.map +1 -1
- package/dist/styles/date-time-button/DateTimeButton.scss +8 -1
- package/dist/styles/events/EditEventModal.scss +2 -0
- package/dist/styles/iframe-page/Page.scss +16 -0
- package/dist/styles/iframe-page/PageBody.scss +4 -0
- package/dist/styles/modals/Modals.scss +16 -0
- package/dist/styles/product-set/EditProductSetElement.scss +1 -0
- package/dist/styles/product-set/ProductSetForm.scss +11 -0
- package/dist/styles/sales/ManualBooking.scss +6 -0
- package/dist/styles/themes/bookedit/index.scss +19 -0
- package/package.json +6 -6
- package/src/events/event-statistic-modal/utils/index.ts +4 -4
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.tsx +212 -0
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.tsx +75 -0
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.tsx +393 -0
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.tsx +98 -0
- package/src/iframe/ProductWithModifierModal/ModifierSetModal/index.ts +1 -0
- package/src/iframe/ProductWithModifierModal/index.ts +1 -0
- package/src/iframe/ProductWithModifierModal/utils.ts +29 -0
- package/src/iframe/activity-card/ActivityCard.stories.tsx +0 -2
- package/src/iframe/activity-card/ActivityCard.tsx +0 -4
- package/src/iframe/event/ticket-description/TicketDescription.tsx +5 -3
- package/src/iframe/order-process/components/BookingSummary/BookingSummary.tsx +2 -0
- package/src/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.tsx +21 -1
- package/src/iframe/order-process/components/BookingSummary/types/index.ts +1 -0
- package/src/iframe/order-process/components/BookingSummary/utils/index.ts +42 -1
- package/src/iframe/order-process/components/CategoryProduct/CategoryProduct.tsx +155 -75
- package/src/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.tsx +58 -1
- package/src/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.tsx +86 -0
- package/src/iframe/order-process/components/CategoryProduct/constants.ts +1 -0
- package/src/iframe/order-process/components/utils/useOnWindowUnmount.ts +25 -0
- package/src/iframe/payment/order-items-table/hooks/useTableData.tsx +84 -14
- package/src/iframe/payment/order-items-table/utils/index.ts +23 -0
- package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +2 -2
- package/src/iframe/payment/payment-page/PaymentPage.tsx +8 -10
- package/src/product-set/form/ProductSetForm.tsx +11 -3
- package/src/product-set/form/ProductsControl.tsx +33 -15
- package/src/product-set/form/context.tsx +5 -0
- package/src/product-set/product/ProductControl.tsx +37 -1
- package/src/product-set/utils/index.ts +19 -0
- package/src/report/ReportRunnerModal/ReportRunnerModal.tsx +2 -2
- package/src/sales/coupon/utils/index.ts +5 -3
- package/src/sales/modals/refund-modal/RefundModal.tsx +15 -6
- package/src/sales/modals/refund-modal/index.ts +7 -2
- package/src/styles/date-time-button/DateTimeButton.scss +8 -1
- package/src/styles/events/EditEventModal.scss +2 -0
- package/src/styles/iframe-page/Page.scss +16 -0
- package/src/styles/iframe-page/PageBody.scss +4 -0
- package/src/styles/modals/Modals.scss +16 -0
- package/src/styles/product-set/EditProductSetElement.scss +1 -0
- package/src/styles/product-set/ProductSetForm.scss +11 -0
- package/src/styles/sales/ManualBooking.scss +6 -0
- package/src/styles/themes/bookedit/index.scss +19 -0
- package/yarn.lock +334 -333
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
1
2
|
import clsx from 'clsx'
|
|
2
3
|
import { Button } from 'react-bootstrap'
|
|
4
|
+
import { isEmpty } from 'lodash'
|
|
3
5
|
import { useTranslation } from 'react-i18next'
|
|
4
6
|
import { FieldValues, RefCallBack, UseFormClearErrors } from 'react-hook-form'
|
|
5
7
|
import {
|
|
6
8
|
Product,
|
|
7
9
|
ProductCategory,
|
|
8
10
|
} from '@licklist/plugins/dist/types/context/sale/menuSteps'
|
|
11
|
+
import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
|
|
9
12
|
import { NumberInput } from '../NumberInput'
|
|
13
|
+
// eslint-disable-next-line
|
|
14
|
+
import { ProductWithModifierSetModal } from '../../../../../ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal'
|
|
10
15
|
|
|
11
|
-
interface FormOrderItem {
|
|
16
|
+
export interface FormOrderItem {
|
|
12
17
|
id: number
|
|
13
18
|
name: string
|
|
14
19
|
price: number
|
|
@@ -17,6 +22,7 @@ interface FormOrderItem {
|
|
|
17
22
|
deposit?: number | null
|
|
18
23
|
quantity: number
|
|
19
24
|
capacity?: number | null
|
|
25
|
+
orderModifiersSets?: OrderModifierByProduct[] | null
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
interface ProductQuantityInputProps {
|
|
@@ -40,6 +46,7 @@ export const ProductQuantityInput = ({
|
|
|
40
46
|
invalid,
|
|
41
47
|
}: ProductQuantityInputProps) => {
|
|
42
48
|
const { t } = useTranslation('Design')
|
|
49
|
+
const [open, handleOpenModal] = useState(false)
|
|
43
50
|
|
|
44
51
|
const onChange = (quantity: number | null) => {
|
|
45
52
|
_onChange({
|
|
@@ -48,12 +55,35 @@ export const ProductQuantityInput = ({
|
|
|
48
55
|
deposit: product?.deposit,
|
|
49
56
|
hasDeposit: category.allowDeposits && product?.deposit < product.price,
|
|
50
57
|
price: product.price,
|
|
58
|
+
orderModifiersSets: [],
|
|
51
59
|
productCategoryId: category.id,
|
|
52
60
|
quantity,
|
|
53
61
|
capacity: product?.capacity,
|
|
54
62
|
})
|
|
55
63
|
}
|
|
56
64
|
|
|
65
|
+
const onChangeWithModifierSets = (productOrder: FormOrderItem) => {
|
|
66
|
+
if (isEmpty(productInfo)) {
|
|
67
|
+
_onChange(productOrder)
|
|
68
|
+
return handleOpenModal(false)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_onChange({
|
|
72
|
+
id: productInfo.id,
|
|
73
|
+
name: productInfo.name,
|
|
74
|
+
deposit: productInfo?.deposit,
|
|
75
|
+
hasDeposit: productInfo.hasDeposit,
|
|
76
|
+
price: productInfo.price,
|
|
77
|
+
orderModifiersSets: productInfo.orderModifiersSets?.concat(
|
|
78
|
+
productOrder.orderModifiersSets,
|
|
79
|
+
),
|
|
80
|
+
productCategoryId: category.id,
|
|
81
|
+
quantity: productInfo.quantity + productOrder.quantity,
|
|
82
|
+
capacity: productInfo?.capacity,
|
|
83
|
+
})
|
|
84
|
+
return handleOpenModal(false)
|
|
85
|
+
}
|
|
86
|
+
|
|
57
87
|
if (product.isSoldOut) {
|
|
58
88
|
return (
|
|
59
89
|
<div className='iframe-event__sold-out-wrapper'>
|
|
@@ -62,6 +92,33 @@ export const ProductQuantityInput = ({
|
|
|
62
92
|
)
|
|
63
93
|
}
|
|
64
94
|
|
|
95
|
+
if ((product as Product).modifiersSet.length) {
|
|
96
|
+
return (
|
|
97
|
+
<>
|
|
98
|
+
<Button
|
|
99
|
+
ref={refCallback}
|
|
100
|
+
disabled={product.isSoldOut}
|
|
101
|
+
className={clsx(
|
|
102
|
+
`iframe-event__${
|
|
103
|
+
productInfo?.quantity ? 'unselect-product' : 'select-product'
|
|
104
|
+
}`,
|
|
105
|
+
invalid && 'error',
|
|
106
|
+
)}
|
|
107
|
+
onClick={() => handleOpenModal(true)}
|
|
108
|
+
>
|
|
109
|
+
+
|
|
110
|
+
</Button>
|
|
111
|
+
<ProductWithModifierSetModal
|
|
112
|
+
show={open}
|
|
113
|
+
onHide={() => handleOpenModal(false)}
|
|
114
|
+
onChange={onChangeWithModifierSets}
|
|
115
|
+
product={product}
|
|
116
|
+
category={category}
|
|
117
|
+
/>
|
|
118
|
+
</>
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
65
122
|
if (product?.maxAmount === 1) {
|
|
66
123
|
return (
|
|
67
124
|
<Button
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Button } from 'react-bootstrap'
|
|
2
|
+
import { useTranslation } from 'react-i18next'
|
|
3
|
+
import { FaTrashAlt } from 'react-icons/fa'
|
|
4
|
+
import { Config } from '@licklist/core'
|
|
5
|
+
import { useIntl } from 'react-intl'
|
|
6
|
+
import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
|
|
7
|
+
import {
|
|
8
|
+
getOrderProductModifiersPrice,
|
|
9
|
+
getModifierName,
|
|
10
|
+
} from '../../../BookingSummary/utils'
|
|
11
|
+
|
|
12
|
+
export interface FormOrderItem {
|
|
13
|
+
id: number
|
|
14
|
+
name: string
|
|
15
|
+
price: number
|
|
16
|
+
productCategoryId: number
|
|
17
|
+
hasDeposit?: boolean
|
|
18
|
+
deposit?: number | null
|
|
19
|
+
quantity: number
|
|
20
|
+
capacity?: number | null
|
|
21
|
+
orderModifiersSets?: OrderModifierByProduct[] | null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface ProductQuantityInputProps {
|
|
25
|
+
modifier: OrderModifierByProduct
|
|
26
|
+
modifierKey: number
|
|
27
|
+
isManualBooking?: boolean
|
|
28
|
+
isSummary? :boolean
|
|
29
|
+
deleteOrderModifier?: (order: number) => void
|
|
30
|
+
editOrderModifierSet?: (order: number) => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const ProductWithModifier = ({
|
|
34
|
+
modifier,
|
|
35
|
+
modifierKey,
|
|
36
|
+
isManualBooking = false,
|
|
37
|
+
isSummary = false,
|
|
38
|
+
deleteOrderModifier,
|
|
39
|
+
editOrderModifierSet,
|
|
40
|
+
}: ProductQuantityInputProps) => {
|
|
41
|
+
const { t } = useTranslation('Design')
|
|
42
|
+
const { formatNumber } = useIntl()
|
|
43
|
+
|
|
44
|
+
const modifierName = getModifierName(modifier)
|
|
45
|
+
|
|
46
|
+
const orderModifierDescription = `${modifier.productQuantity}`
|
|
47
|
+
|
|
48
|
+
const modifierPrice = getOrderProductModifiersPrice(modifier)
|
|
49
|
+
|
|
50
|
+
const fullModifiersPrice = formatNumber(modifierPrice, {
|
|
51
|
+
style: 'currency',
|
|
52
|
+
currency: Config.Currency.GBP,
|
|
53
|
+
})
|
|
54
|
+
return (
|
|
55
|
+
<div
|
|
56
|
+
key={modifierKey}
|
|
57
|
+
className='d-flex p-2 justify-content-between align-items-center'
|
|
58
|
+
>
|
|
59
|
+
<div className='d-flex'>
|
|
60
|
+
<p className='font-weight-bold w-25 pr-4'>{`${orderModifierDescription} x`}</p>
|
|
61
|
+
<p>{modifierName ? ` ${modifierName}` : t('withoutModifier')}</p>
|
|
62
|
+
</div>
|
|
63
|
+
{isManualBooking || isSummary ? (
|
|
64
|
+
<p className='price'>{fullModifiersPrice}</p>
|
|
65
|
+
) : (
|
|
66
|
+
<div>
|
|
67
|
+
<Button
|
|
68
|
+
className='ml-2'
|
|
69
|
+
variant='link'
|
|
70
|
+
onClick={() => editOrderModifierSet(modifierKey)}
|
|
71
|
+
>
|
|
72
|
+
{t('customise')}
|
|
73
|
+
</Button>
|
|
74
|
+
|
|
75
|
+
<Button
|
|
76
|
+
className='ml-2'
|
|
77
|
+
variant='link'
|
|
78
|
+
onClick={() => deleteOrderModifier(modifierKey)}
|
|
79
|
+
>
|
|
80
|
+
<FaTrashAlt />
|
|
81
|
+
</Button>
|
|
82
|
+
</div>
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MAX_PRODUCT_NUMBER = 100000 // max number
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
export type UseOnWindowUnmountProps = {
|
|
4
|
+
onBeforeUnload: (event: Event) => void
|
|
5
|
+
onPopState: (event: Event) => void
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const useOnWindowUnmount = ({
|
|
9
|
+
onBeforeUnload,
|
|
10
|
+
onPopState,
|
|
11
|
+
}: UseOnWindowUnmountProps) => {
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
window.history.pushState(null, '', window.location.pathname)
|
|
14
|
+
window.addEventListener('beforeunload', onBeforeUnload)
|
|
15
|
+
window.addEventListener('popstate', onPopState)
|
|
16
|
+
|
|
17
|
+
return () => {
|
|
18
|
+
window.removeEventListener('beforeunload', onBeforeUnload)
|
|
19
|
+
window.removeEventListener('popstate', onPopState)
|
|
20
|
+
}
|
|
21
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
22
|
+
}, [])
|
|
23
|
+
|
|
24
|
+
return null
|
|
25
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useMemo } from 'react'
|
|
2
|
-
import { uniqueId } from 'lodash'
|
|
2
|
+
import { uniqueId, flatMap, flatten, map } from 'lodash'
|
|
3
3
|
import { useIntl } from 'react-intl'
|
|
4
4
|
import { useTranslation } from 'react-i18next'
|
|
5
5
|
import { Product } from '@licklist/core/dist/DataMapper/Product/ProductDataMapper'
|
|
6
|
+
import { OrderModifier } from '@licklist/core/dist/DataMapper/Order/OrderModifierDataMapper'
|
|
6
7
|
import {
|
|
7
8
|
PAYMENT_TYPE_VAT,
|
|
8
9
|
PAYMENT_TYPE_FEE,
|
|
@@ -12,6 +13,10 @@ import { StaticTableData } from '../../../../table'
|
|
|
12
13
|
import { getProductQuantityAndPrice, getTotalSumByCategory } from '../utils'
|
|
13
14
|
import { OrderItemsTableProps, SummaryItem } from '../types'
|
|
14
15
|
import { getOrderSummaryItems } from '../utils/paymentSummary'
|
|
16
|
+
import { Order } from '@licklist/core/dist/DataMapper'
|
|
17
|
+
import { OrderPayment } from '@licklist/core/dist/DataMapper/Order/OrderPaymentDataMapper'
|
|
18
|
+
import { OrderProduct } from '@licklist/core/dist/DataMapper/Order/OrderProductDataMapper'
|
|
19
|
+
import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
|
|
15
20
|
|
|
16
21
|
const CURRENCY_DEFAULT = 'GBP'
|
|
17
22
|
export const PAYMENT_TYPE_TRANSLATE_KEYS = {
|
|
@@ -50,19 +55,67 @@ export const useTableData = ({
|
|
|
50
55
|
),
|
|
51
56
|
})
|
|
52
57
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
order
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
const reworkProductStructure = (order: OrderProduct) =>
|
|
59
|
+
order
|
|
60
|
+
? flatMap(order, (item) => {
|
|
61
|
+
if (!item || !Array.isArray(item)) return []
|
|
62
|
+
return item.map((modGroup, idx) => ({
|
|
63
|
+
deletedAt: order.deletedAt ?? null,
|
|
64
|
+
id: `${order.id}-${idx + 1}`, // Ensuring uniqueness with string concatenation
|
|
65
|
+
orderId: order.orderId ?? null,
|
|
66
|
+
price: order.price ?? 0,
|
|
67
|
+
productId: order.productId ?? '',
|
|
68
|
+
quantity: modGroup.productQuantity ?? 1,
|
|
69
|
+
deposit: order.deposit ?? 0,
|
|
70
|
+
orderProductModifiers: modGroup.modifiers.map((mod) => ({
|
|
71
|
+
modifierId: mod.modifierId ?? '',
|
|
72
|
+
price: mod.price ?? 0,
|
|
73
|
+
productId: mod.productId ?? '',
|
|
74
|
+
quantity: mod.quantity ?? 1,
|
|
75
|
+
modifierSetId: mod.modifierSetId ?? '',
|
|
76
|
+
modifier: mod.modifier ?? null,
|
|
77
|
+
})),
|
|
78
|
+
}))
|
|
79
|
+
})
|
|
80
|
+
: []
|
|
81
|
+
|
|
82
|
+
const renderProductItem = ({
|
|
83
|
+
product,
|
|
84
|
+
productsForCategory,
|
|
85
|
+
}: {
|
|
86
|
+
product: OrderProduct
|
|
87
|
+
productsForCategory: Product[]
|
|
88
|
+
}) => {
|
|
89
|
+
if (product.quantity === 0) {
|
|
90
|
+
return null
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const name =
|
|
94
|
+
productsForCategory.find((item) => item.id === product.productId)?.name || ''
|
|
58
95
|
|
|
96
|
+
return {
|
|
97
|
+
key: product.id,
|
|
98
|
+
name,
|
|
99
|
+
quantity: (
|
|
100
|
+
<div className='quantity'>
|
|
101
|
+
<div className='multiplier'>x</div>
|
|
102
|
+
{product.quantity}
|
|
103
|
+
</div>
|
|
104
|
+
),
|
|
105
|
+
price: formatPrice(product.price),
|
|
106
|
+
modifier: product?.orderProductModifiers?.map(renderModifierItem) || [],
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const renderModifierItem = (orderModifier: OrderModifier) => {
|
|
111
|
+
const { quantity, modifier, modifierId, price } = orderModifier
|
|
59
112
|
if (quantity === 0) {
|
|
60
113
|
return null
|
|
61
114
|
}
|
|
62
115
|
|
|
63
116
|
return {
|
|
64
|
-
key:
|
|
65
|
-
name:
|
|
117
|
+
key: modifierId,
|
|
118
|
+
name: ` - ${modifier?.name || ''}`,
|
|
66
119
|
quantity: (
|
|
67
120
|
<div className='quantity'>
|
|
68
121
|
<div className='multiplier'>x</div>
|
|
@@ -80,15 +133,33 @@ export const useTableData = ({
|
|
|
80
133
|
|
|
81
134
|
return productCategories.reduce(
|
|
82
135
|
(previousValues: StaticTableData[], categoryId) => {
|
|
83
|
-
const
|
|
136
|
+
const productsForCategory = order?.products.filter(
|
|
84
137
|
(product) => product.productCategoryId === categoryId,
|
|
85
138
|
)
|
|
86
139
|
|
|
140
|
+
const products = order.orderProducts.filter((el) =>
|
|
141
|
+
productsForCategory
|
|
142
|
+
.map((product) => product.id)
|
|
143
|
+
.includes(el.productId),
|
|
144
|
+
)
|
|
145
|
+
|
|
87
146
|
if (!products.length) {
|
|
88
147
|
return previousValues
|
|
89
148
|
}
|
|
90
|
-
|
|
91
|
-
|
|
149
|
+
const productsWithReworkedModifier = products.map((product) => {
|
|
150
|
+
if (!product.orderProductModifiers.length) return product
|
|
151
|
+
return reworkProductStructure(product)
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const filteredProducts = flatten(productsWithReworkedModifier).map(
|
|
155
|
+
(product) =>
|
|
156
|
+
renderProductItem({ product , productsForCategory }),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
const productWithModifier = flatMap(filteredProducts, (item) => [
|
|
160
|
+
item,
|
|
161
|
+
...item.modifier,
|
|
162
|
+
])
|
|
92
163
|
|
|
93
164
|
if (!filteredProducts.length) {
|
|
94
165
|
return previousValues
|
|
@@ -96,8 +167,8 @@ export const useTableData = ({
|
|
|
96
167
|
|
|
97
168
|
return [
|
|
98
169
|
...previousValues,
|
|
99
|
-
renderCategoryItem(
|
|
100
|
-
...
|
|
170
|
+
renderCategoryItem(productsForCategory),
|
|
171
|
+
...productWithModifier,
|
|
101
172
|
]
|
|
102
173
|
},
|
|
103
174
|
[],
|
|
@@ -133,6 +204,5 @@ export const useTableData = ({
|
|
|
133
204
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
134
205
|
[order, externalDiscount, isPaymentProcessed],
|
|
135
206
|
)
|
|
136
|
-
|
|
137
207
|
return data
|
|
138
208
|
}
|
|
@@ -6,6 +6,7 @@ import { Product } from '@licklist/core/dist/DataMapper/Product/ProductDataMappe
|
|
|
6
6
|
import { PAYMENT_TYPE_DISCOUNT } from '@licklist/core/dist/DataMapper/Order/PaymentDataMapper'
|
|
7
7
|
import { PaymentDetail } from '@licklist/core/dist/DataMapper/Order/PaymentDetailDataMapper'
|
|
8
8
|
import { PAYMENT_TYPE_TRANSLATE_KEYS } from '../hooks/useTableData'
|
|
9
|
+
import { OrderModifier } from '@licklist/core/dist/DataMapper/Order/OrderModifierDataMapper'
|
|
9
10
|
|
|
10
11
|
const TRANSLATE_KEYS = {
|
|
11
12
|
totalAmount: 'totalPaid',
|
|
@@ -28,6 +29,7 @@ export const calculateTotalPrice = (
|
|
|
28
29
|
order: Order,
|
|
29
30
|
externalPaymentDetails?: ExternalPaymnetDetail[],
|
|
30
31
|
) => {
|
|
32
|
+
|
|
31
33
|
const totalPrice =
|
|
32
34
|
order?.orderProducts?.reduce(
|
|
33
35
|
(total: number, product) =>
|
|
@@ -125,5 +127,26 @@ export const getTotalSumByCategory = (
|
|
|
125
127
|
product,
|
|
126
128
|
)
|
|
127
129
|
|
|
130
|
+
const modifierFromProduct = orderProducts.find(
|
|
131
|
+
(orderProduct) => orderProduct.productId === product.id,
|
|
132
|
+
)?.orderProductModifiers
|
|
133
|
+
if (modifierFromProduct) {
|
|
134
|
+
const modifierPrice = modifierFromProduct.reduce(
|
|
135
|
+
(prevSum: number, { modifiers }) => {
|
|
136
|
+
const modifiersPrices = modifiers.reduce(
|
|
137
|
+
(prevSumModifier: number, modifier: OrderModifier) =>
|
|
138
|
+
prevSumModifier + modifier.price * modifier.quantity,
|
|
139
|
+
0,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return prevSum + modifiersPrices
|
|
143
|
+
},
|
|
144
|
+
0,
|
|
145
|
+
)
|
|
146
|
+
const priceWithModifier = price + modifierPrice
|
|
147
|
+
|
|
148
|
+
return prevSum + priceWithModifier * quantity
|
|
149
|
+
}
|
|
150
|
+
|
|
128
151
|
return prevSum + price * quantity
|
|
129
152
|
}, 0)
|
|
@@ -23,7 +23,7 @@ const paymentNotProcessedSummary = ({
|
|
|
23
23
|
? getExternalPaymentDetail(paymentDetail)
|
|
24
24
|
: undefined
|
|
25
25
|
|
|
26
|
-
const total = calculateTotalPrice(order, externalPaymentDetail)
|
|
26
|
+
const total = order?.fullAmount || calculateTotalPrice(order, externalPaymentDetail)
|
|
27
27
|
|
|
28
28
|
const summaryItems: SummaryItem[] = [
|
|
29
29
|
{
|
|
@@ -58,7 +58,7 @@ const processedPaymentSummary = ({
|
|
|
58
58
|
price: getPaymentValueByType(order.payments, key),
|
|
59
59
|
}))
|
|
60
60
|
|
|
61
|
-
const total = calculateTotalPrice(order, externalPaymentDetail)
|
|
61
|
+
const total = order.fullAmount || calculateTotalPrice(order, externalPaymentDetail)
|
|
62
62
|
|
|
63
63
|
const totalDiscount = calculateTotalDiscount(order.payments)
|
|
64
64
|
|
|
@@ -131,6 +131,12 @@ export const PaymentPage = ({
|
|
|
131
131
|
const totalPaidWithRemainingToPay =
|
|
132
132
|
data?.amount_to_pay && !!Number(data?.amount_to_pay)
|
|
133
133
|
|
|
134
|
+
const totalBooked = paymentMetadata
|
|
135
|
+
? paymentMetadata.paid
|
|
136
|
+
? paymentMetadata.total - paymentMetadata.paid
|
|
137
|
+
: paymentMetadata.total
|
|
138
|
+
: orderTotalAmountByFormValues + (bookingSummaryProps?.transactionFee ?? 0)
|
|
139
|
+
|
|
134
140
|
return (
|
|
135
141
|
<Page className='payment_link'>
|
|
136
142
|
{/* TODO wait for Brad's design for close and go back buttons */}
|
|
@@ -156,16 +162,8 @@ export const PaymentPage = ({
|
|
|
156
162
|
<BookingSummary
|
|
157
163
|
{...bookingSummaryProps}
|
|
158
164
|
isPaymentPage
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
amount={
|
|
162
|
-
paymentMetadata
|
|
163
|
-
? paymentMetadata.total
|
|
164
|
-
: orderTotalAmountByFormValues +
|
|
165
|
-
(bookingSummaryProps?.transactionFee || 0)
|
|
166
|
-
}
|
|
167
|
-
/>
|
|
168
|
-
}
|
|
165
|
+
headerTitle={t('totalBooking')}
|
|
166
|
+
headerComponent={<SummaryTotalBlock amount={totalBooked} />}
|
|
169
167
|
footer={
|
|
170
168
|
<div className='d-flex flex-column justify-content-between'>
|
|
171
169
|
{paymentMetadata ? (
|
|
@@ -6,6 +6,7 @@ import { TFunction, useTranslation } from 'react-i18next'
|
|
|
6
6
|
import { VenueMapSet } from '@licklist/core/dist/DataMapper/Product/VenueMapSetDataMapper'
|
|
7
7
|
import { ServerError } from '@licklist/plugins/dist/hooks/Api/useHttpQuery'
|
|
8
8
|
import FormErrorService from '@licklist/plugins/dist/services/Form/FormErrorService'
|
|
9
|
+
import { ModifierSet } from '@licklist/core/dist/DataMapper/Product/ModifierSetDataMapper'
|
|
9
10
|
|
|
10
11
|
import { isEqual } from 'lodash'
|
|
11
12
|
// eslint-disable-next-line max-len
|
|
@@ -22,7 +23,11 @@ import {
|
|
|
22
23
|
import { Step } from '../types'
|
|
23
24
|
import { ProductSetContextProvider, ProductSetLoadingContext } from './context'
|
|
24
25
|
import { SelectItem } from '../../types/generic/SelectItem'
|
|
25
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
checkAvailableTimesErrors,
|
|
28
|
+
updateModifiersSetAtProductSetForm,
|
|
29
|
+
getFilteredTemplates,
|
|
30
|
+
} from '../utils'
|
|
26
31
|
import { ErrorModal } from '../../iframe/order-process/components/ErrorModal'
|
|
27
32
|
|
|
28
33
|
export interface WithIsLoading {
|
|
@@ -62,6 +67,7 @@ export interface ProductSetFormProps
|
|
|
62
67
|
saleDeadline?: number
|
|
63
68
|
isCreateNewOverrides?: boolean
|
|
64
69
|
timeZone: string
|
|
70
|
+
modifiersSetList?: ModifierSet[]
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
export function ProductSetForm({
|
|
@@ -71,6 +77,7 @@ export function ProductSetForm({
|
|
|
71
77
|
onSubmitAndRedirect,
|
|
72
78
|
onSubmitNoRedirect,
|
|
73
79
|
productGroupList,
|
|
80
|
+
modifiersSetList,
|
|
74
81
|
serverErrors,
|
|
75
82
|
providerHasMap = false,
|
|
76
83
|
venueMapSets = [],
|
|
@@ -95,7 +102,7 @@ export function ProductSetForm({
|
|
|
95
102
|
const [errorMessage, setErrorMessage] = useState('')
|
|
96
103
|
|
|
97
104
|
const form = useForm<ProductSetFormValues>({
|
|
98
|
-
defaultValues,
|
|
105
|
+
defaultValues: updateModifiersSetAtProductSetForm(defaultValues),
|
|
99
106
|
mode: 'onChange',
|
|
100
107
|
})
|
|
101
108
|
|
|
@@ -122,7 +129,7 @@ export function ProductSetForm({
|
|
|
122
129
|
if (!defaultValues || isEqual(defaultValues, formValues)) {
|
|
123
130
|
return
|
|
124
131
|
}
|
|
125
|
-
reset(defaultValues)
|
|
132
|
+
reset(updateModifiersSetAtProductSetForm(defaultValues))
|
|
126
133
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
127
134
|
}, [defaultValues])
|
|
128
135
|
|
|
@@ -162,6 +169,7 @@ export function ProductSetForm({
|
|
|
162
169
|
<ProductSetContextProvider
|
|
163
170
|
productGroupList={productGroupList}
|
|
164
171
|
providerHasMap={providerHasMap}
|
|
172
|
+
modifiersSetList={modifiersSetList}
|
|
165
173
|
venueMapSets={venueMapSets}
|
|
166
174
|
providerHasBookingManagement={providerHasBookingManagement}
|
|
167
175
|
zones={zones}
|
|
@@ -49,6 +49,8 @@ const getDefaultProductValue = (sort: number): Product => ({
|
|
|
49
49
|
maxQuantity: null,
|
|
50
50
|
totalQuantity: 0,
|
|
51
51
|
isAvailable: true,
|
|
52
|
+
modifiersSet: [],
|
|
53
|
+
modifiersSetsId: [],
|
|
52
54
|
isSoldOut: false,
|
|
53
55
|
isRequired: false,
|
|
54
56
|
isUnlimited: false,
|
|
@@ -139,6 +141,16 @@ export function ProductsControl({
|
|
|
139
141
|
],
|
|
140
142
|
})
|
|
141
143
|
|
|
144
|
+
const modifierSets = useWatch({
|
|
145
|
+
control,
|
|
146
|
+
name: [
|
|
147
|
+
...fields.map(
|
|
148
|
+
(_, index) =>
|
|
149
|
+
`${productControlFieldName}.${index}.modifiersSet` as const,
|
|
150
|
+
),
|
|
151
|
+
],
|
|
152
|
+
})
|
|
153
|
+
|
|
142
154
|
const categoryProductErrors =
|
|
143
155
|
errors?.steps?.[stepIndex]?.productCategories?.[productCategoryIndex]
|
|
144
156
|
?.products
|
|
@@ -199,6 +211,7 @@ export function ProductsControl({
|
|
|
199
211
|
: isOverrides && !!product.originalProductId
|
|
200
212
|
|
|
201
213
|
const isNewProductOverrides = isCreateNewOverrides && !!product.id
|
|
214
|
+
const modifiersSets = modifierSets[index]?.length || 0
|
|
202
215
|
|
|
203
216
|
return (
|
|
204
217
|
<Controller
|
|
@@ -226,21 +239,26 @@ export function ProductsControl({
|
|
|
226
239
|
edit={() => edit(index)}
|
|
227
240
|
secondaryBadge={getBadgeConfig(categoryType, t(categoryType))}
|
|
228
241
|
subTitle={
|
|
229
|
-
<div className='
|
|
230
|
-
<div className='product-set-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
<div className='d-flex justify-content-between'>
|
|
243
|
+
<div className='product-set-badges-container'>
|
|
244
|
+
<div className='product-set-subtitle-dot product-set-subtitle-product-dot' />
|
|
245
|
+
<span>
|
|
246
|
+
{`£${prices[index]} ${t('each')} - ${t('qty')}:${
|
|
247
|
+
!isUnlimitedQuantities[index]
|
|
248
|
+
? ` ${quantities[index]}`
|
|
249
|
+
: t(' unlimited')
|
|
250
|
+
} ${
|
|
251
|
+
!isUnlimitedQuantities[index]
|
|
252
|
+
? ` - ${t('possibleRevenue')} £${
|
|
253
|
+
prices[index] * quantities[index]
|
|
254
|
+
}`
|
|
255
|
+
: ''
|
|
256
|
+
} `}
|
|
257
|
+
</span>
|
|
258
|
+
</div>
|
|
259
|
+
{!!modifiersSets && (
|
|
260
|
+
<Badge className='modifier-badge'>{`${modifiersSets} ${t('modifiersSets')}`}</Badge>
|
|
261
|
+
)}
|
|
244
262
|
</div>
|
|
245
263
|
}
|
|
246
264
|
modalLabel={t('addNewProduct')}
|
|
@@ -7,15 +7,18 @@ import {
|
|
|
7
7
|
Dispatch,
|
|
8
8
|
} from 'react'
|
|
9
9
|
import { VenueMapSet } from '@licklist/core/dist/DataMapper/Product/VenueMapSetDataMapper'
|
|
10
|
+
import { ModifierSet } from '@licklist/core/dist/DataMapper/Product/ModifierSetDataMapper'
|
|
10
11
|
// eslint-disable-next-line max-len
|
|
11
12
|
import { ProviderBookingManagementSetting } from '@licklist/core/dist/DataMapper/Provider/ProviderBookingManagementSettingDataMapper'
|
|
12
13
|
import { Zone } from '@licklist/core/dist/DataMapper/Provider/ZoneDataMapper'
|
|
13
14
|
import { SelectItem } from '../../types/generic/SelectItem'
|
|
14
15
|
|
|
16
|
+
|
|
15
17
|
interface LoadingContext {
|
|
16
18
|
isLoading: boolean
|
|
17
19
|
setLoading: (loading: boolean) => void
|
|
18
20
|
productGroupList?: SelectItem[]
|
|
21
|
+
modifiersSetList?: ModifierSet[] | null
|
|
19
22
|
providerHasMap?: boolean | null
|
|
20
23
|
venueMapSets?: VenueMapSet[]
|
|
21
24
|
providerHasBookingManagement?: ProviderBookingManagementSetting['hasBookingManagement']
|
|
@@ -43,6 +46,7 @@ type ProductSetContextProviderProps = PropsWithChildren<
|
|
|
43
46
|
export function ProductSetContextProvider({
|
|
44
47
|
children,
|
|
45
48
|
productGroupList = [],
|
|
49
|
+
modifiersSetList =[],
|
|
46
50
|
providerHasMap = false,
|
|
47
51
|
venueMapSets = [],
|
|
48
52
|
providerHasBookingManagement,
|
|
@@ -62,6 +66,7 @@ export function ProductSetContextProvider({
|
|
|
62
66
|
isLoading: loading,
|
|
63
67
|
setLoading,
|
|
64
68
|
productGroupList,
|
|
69
|
+
modifiersSetList,
|
|
65
70
|
providerHasMap,
|
|
66
71
|
venueMapSets,
|
|
67
72
|
providerHasBookingManagement,
|