@infosoftas/s4-orders-js-sdk 0.0.1-alpha2 → 0.0.1-alpha2b
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/package.json +1 -1
- package/src/App.tsx +97 -33
- package/src/api/InvoiceApi.ts +25 -0
- package/src/api/OrdersApi.ts +1 -0
- package/src/assets/styles/forms.scss +59 -0
- package/src/assets/styles/general.scss +8 -0
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/EHFForm/EHFForm.tsx +125 -0
- package/src/components/FormFields/AddressField.tsx +5 -6
- package/src/components/FormFields/EmailField.tsx +5 -4
- package/src/components/FormFields/FormFields.helper.ts +9 -0
- package/src/components/FormFields/FormFieldsMapper.ts +9 -0
- package/src/components/FormFields/NameField.tsx +5 -4
- package/src/components/FormFields/PhoneField.tsx +5 -6
- package/src/components/FormFields/ToggleFiled.tsx +58 -0
- package/src/components/OIOForm/OIOForm.tsx +141 -0
- package/src/components/OrderForm/OrderForm.tsx +55 -3
- package/src/enums/general.ts +12 -0
- package/src/types/api.ts +1 -0
- package/src/types/general.ts +10 -1
- package/src/types/order.ts +11 -0
- package/src/utils/order.helper.ts +104 -1
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { FC, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
FormTypeEnum,
|
|
5
|
+
MessageEventTypeEnum,
|
|
6
|
+
PaymentMethodEnum,
|
|
7
|
+
} from './enums/general';
|
|
4
8
|
import useMessageEvent from './hooks/useMessageEvent';
|
|
5
9
|
import OrderForm from './components/OrderForm/OrderForm';
|
|
10
|
+
import OIOForm from './components/OIOForm/OIOForm';
|
|
11
|
+
import EHFForm from './components/EHFForm/EHFForm';
|
|
6
12
|
import Loader from './components/Loader/Loader';
|
|
7
13
|
import MainIframe from './components/MainIframe/MainIframe';
|
|
8
14
|
import Alert from './components/Alert/Alert';
|
|
@@ -27,6 +33,7 @@ const App: FC<ConfigType> = ({
|
|
|
27
33
|
redirectUrl,
|
|
28
34
|
showIframe,
|
|
29
35
|
paymentMethodsOptions,
|
|
36
|
+
invoiceAddressSelection,
|
|
30
37
|
availablePaymentMethods = [],
|
|
31
38
|
language = 'en-US',
|
|
32
39
|
merchantAgreementUrl = '',
|
|
@@ -34,6 +41,11 @@ const App: FC<ConfigType> = ({
|
|
|
34
41
|
successText: 'Order successful completed!',
|
|
35
42
|
failureText: 'Something went wrong!',
|
|
36
43
|
buttonText: 'Start',
|
|
44
|
+
submitButtonText: 'Start',
|
|
45
|
+
backButtonText: 'Back',
|
|
46
|
+
verifyButtonText: 'Verify',
|
|
47
|
+
organizationNumberLabel: 'CVR',
|
|
48
|
+
glnLabel: 'GLN',
|
|
37
49
|
},
|
|
38
50
|
}) => {
|
|
39
51
|
const [loading, setLoading] = useState<boolean>(false);
|
|
@@ -45,6 +57,7 @@ const App: FC<ConfigType> = ({
|
|
|
45
57
|
const [failedMsg, setFailedMsg] = useState<string>('');
|
|
46
58
|
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
47
59
|
const [orderInfo, setOrderInfo] = useState<OrderInfoType | null>(null);
|
|
60
|
+
const [formType, setFormType] = useState(FormTypeEnum.ORDER);
|
|
48
61
|
|
|
49
62
|
useEffect(() => {
|
|
50
63
|
if (apiKey) {
|
|
@@ -107,6 +120,7 @@ const App: FC<ConfigType> = ({
|
|
|
107
120
|
setIsFailed(true);
|
|
108
121
|
setLoading(false);
|
|
109
122
|
setShowOrderForm(true);
|
|
123
|
+
setFormType(FormTypeEnum.ORDER);
|
|
110
124
|
}
|
|
111
125
|
};
|
|
112
126
|
|
|
@@ -190,18 +204,15 @@ const App: FC<ConfigType> = ({
|
|
|
190
204
|
data?.paymentMethod === PaymentMethodEnum.Email ||
|
|
191
205
|
data?.paymentMethod === PaymentMethodEnum.Invoice
|
|
192
206
|
) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
top?.location?.origin || '*'
|
|
203
|
-
);
|
|
204
|
-
}
|
|
207
|
+
messageCallback({
|
|
208
|
+
orderId: data.orderId || orderId || '',
|
|
209
|
+
agreementId: '',
|
|
210
|
+
orderInfo: data || orderInfo || null,
|
|
211
|
+
});
|
|
212
|
+
} else if (data?.paymentMethod === PaymentMethodEnum.EHF) {
|
|
213
|
+
setFormType(FormTypeEnum.EHF);
|
|
214
|
+
} else if (data?.paymentMethod === PaymentMethodEnum.OIO) {
|
|
215
|
+
setFormType(FormTypeEnum.OIO);
|
|
205
216
|
} else if (url) {
|
|
206
217
|
if (
|
|
207
218
|
showIframe &&
|
|
@@ -218,6 +229,18 @@ const App: FC<ConfigType> = ({
|
|
|
218
229
|
setIframeSrc(null);
|
|
219
230
|
};
|
|
220
231
|
|
|
232
|
+
const handleInvoiceBack = () => {
|
|
233
|
+
setFormType(FormTypeEnum.ORDER);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const handleInvoiceForm = async () => {
|
|
237
|
+
await messageCallback({
|
|
238
|
+
orderId: orderId || '',
|
|
239
|
+
agreementId: '',
|
|
240
|
+
orderInfo: orderInfo || null,
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
|
|
221
244
|
if (window !== top) {
|
|
222
245
|
return null;
|
|
223
246
|
}
|
|
@@ -237,26 +260,67 @@ const App: FC<ConfigType> = ({
|
|
|
237
260
|
</div>
|
|
238
261
|
)}
|
|
239
262
|
{!iframeSrc && showOrderForm && (
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
263
|
+
<>
|
|
264
|
+
{formType === FormTypeEnum.OIO && (
|
|
265
|
+
<OIOForm
|
|
266
|
+
onBack={handleInvoiceBack}
|
|
267
|
+
callback={handleInvoiceForm}
|
|
268
|
+
backButtonText={settings?.backButtonText}
|
|
269
|
+
verifyButtonText={settings?.verifyButtonText}
|
|
270
|
+
organizationNumberLabel={
|
|
271
|
+
settings?.organizationNumberLabel
|
|
272
|
+
}
|
|
273
|
+
glnLabel={settings?.glnLabel}
|
|
274
|
+
/>
|
|
275
|
+
)}
|
|
276
|
+
{formType === FormTypeEnum.EHF && (
|
|
277
|
+
<EHFForm
|
|
278
|
+
onBack={handleInvoiceBack}
|
|
279
|
+
callback={handleInvoiceForm}
|
|
280
|
+
backButtonText={settings?.backButtonText}
|
|
281
|
+
verifyButtonText={settings?.verifyButtonText}
|
|
282
|
+
organizationNumberLabel={
|
|
283
|
+
settings?.organizationNumberLabel
|
|
284
|
+
}
|
|
285
|
+
/>
|
|
286
|
+
)}
|
|
287
|
+
{formType !== FormTypeEnum.OIO &&
|
|
288
|
+
formType !== FormTypeEnum.EHF && (
|
|
289
|
+
<OrderForm
|
|
290
|
+
callback={handleForm}
|
|
291
|
+
templatePackageId={templatePackageId}
|
|
292
|
+
subscriberId={subscriberId}
|
|
293
|
+
userId={userId}
|
|
294
|
+
identityProviderId={identityProviderId}
|
|
295
|
+
organizationId={organizationId}
|
|
296
|
+
paymentMethods={availablePaymentMethods}
|
|
297
|
+
submitButtonText={
|
|
298
|
+
settings?.submitButtonText
|
|
299
|
+
}
|
|
300
|
+
paymentMethodLabel={
|
|
301
|
+
settings?.paymentMethodLabel
|
|
302
|
+
}
|
|
303
|
+
errorReqMsg={settings?.errorReqMsg}
|
|
304
|
+
errorInvalidEmailMsg={
|
|
305
|
+
settings?.errorInvalidEmailMsg
|
|
306
|
+
}
|
|
307
|
+
errorInvalidPhoneMsg={
|
|
308
|
+
settings?.errorInvalidPhoneMsg
|
|
309
|
+
}
|
|
310
|
+
defaultValues={settings?.orderDefaultValues}
|
|
311
|
+
redirectUrl={redirectUrl}
|
|
312
|
+
showIframe={showIframe}
|
|
313
|
+
paymentMethodsOptions={
|
|
314
|
+
paymentMethodsOptions
|
|
315
|
+
}
|
|
316
|
+
language={language}
|
|
317
|
+
merchantAgreementUrl={merchantAgreementUrl}
|
|
318
|
+
invoiceAddressSelection={
|
|
319
|
+
invoiceAddressSelection
|
|
320
|
+
}
|
|
321
|
+
/>
|
|
322
|
+
)}
|
|
323
|
+
</>
|
|
260
324
|
)}
|
|
261
325
|
{showIframe && <MainIframe iframeSrc={iframeSrc} />}
|
|
262
326
|
{isConfirmed && (
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import fetcher from '../utils/fetcher';
|
|
2
|
+
|
|
3
|
+
type RequestInvoiceLookupType = {
|
|
4
|
+
network: string;
|
|
5
|
+
value: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type InvoiceLookupResponseType = {
|
|
9
|
+
recievesInvoice: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const invoiceLookup = (
|
|
13
|
+
body: RequestInvoiceLookupType
|
|
14
|
+
): Promise<InvoiceLookupResponseType> =>
|
|
15
|
+
fetcher<InvoiceLookupResponseType, RequestInvoiceLookupType>({
|
|
16
|
+
method: 'POST',
|
|
17
|
+
url: '/invoicelookup',
|
|
18
|
+
headers: {
|
|
19
|
+
'S4-ORDERS-API-KEY':
|
|
20
|
+
sessionStorage.getItem('sdk_api_key') ||
|
|
21
|
+
process.env.API_KEY ||
|
|
22
|
+
'',
|
|
23
|
+
},
|
|
24
|
+
body,
|
|
25
|
+
}) as Promise<InvoiceLookupResponseType>;
|
package/src/api/OrdersApi.ts
CHANGED
|
@@ -102,4 +102,63 @@
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.sdk-on-off-label {
|
|
108
|
+
margin-right: 0.5rem;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.sdk-on-off {
|
|
112
|
+
position: relative;
|
|
113
|
+
display : inline-block;
|
|
114
|
+
width : 60px;
|
|
115
|
+
height : 28px;
|
|
116
|
+
|
|
117
|
+
input {
|
|
118
|
+
opacity: 0;
|
|
119
|
+
width : 0;
|
|
120
|
+
height : 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
input:checked+.slider:before {
|
|
124
|
+
-webkit-transform: translateX(32px);
|
|
125
|
+
-ms-transform : translateX(32px);
|
|
126
|
+
transform : translateX(32px);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
input:checked+.slider {
|
|
130
|
+
background-color: $primary-color;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.slider {
|
|
134
|
+
position : absolute;
|
|
135
|
+
cursor : pointer;
|
|
136
|
+
top : 0;
|
|
137
|
+
left : 0;
|
|
138
|
+
right : 0;
|
|
139
|
+
bottom : 0;
|
|
140
|
+
background-color : $input-border-disabled-color;
|
|
141
|
+
-webkit-transition: .4s;
|
|
142
|
+
transition : .4s;
|
|
143
|
+
|
|
144
|
+
&:before {
|
|
145
|
+
position : absolute;
|
|
146
|
+
content : "";
|
|
147
|
+
height : 24px;
|
|
148
|
+
width : 24px;
|
|
149
|
+
left : 2px;
|
|
150
|
+
bottom : 2px;
|
|
151
|
+
background-color : white;
|
|
152
|
+
-webkit-transition: .4s;
|
|
153
|
+
transition : .4s;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
&.round {
|
|
157
|
+
border-radius: 28px;
|
|
158
|
+
|
|
159
|
+
&:before {
|
|
160
|
+
border-radius: 50%;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
105
164
|
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { FC, useState } from 'react';
|
|
2
|
+
import { FormProvider, useForm, SubmitHandler } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { invoiceLookup } from '../../api/InvoiceApi';
|
|
5
|
+
import Alert from '../Alert/Alert';
|
|
6
|
+
import Button from '../Button/Button';
|
|
7
|
+
import InputField from '../FormFields/InputField';
|
|
8
|
+
import {
|
|
9
|
+
prepareErrorMessage,
|
|
10
|
+
prepareErrorsArrayMessage,
|
|
11
|
+
} from '../../utils/helper';
|
|
12
|
+
import { InvoiceLookupNetworkEnum } from '../../enums/general';
|
|
13
|
+
import { ErrorsMsg } from '../../types/general';
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
callback: (value: string) => void;
|
|
17
|
+
onBack: () => void;
|
|
18
|
+
backButtonText?: string;
|
|
19
|
+
verifyButtonText?: string;
|
|
20
|
+
organizationNumberLabel?: string;
|
|
21
|
+
className?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type EHFFormInputsType = {
|
|
25
|
+
organizationNumber: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const initialData = {
|
|
29
|
+
organizationNumber: '',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const EHFForm: FC<Props> = ({
|
|
33
|
+
callback,
|
|
34
|
+
onBack,
|
|
35
|
+
backButtonText = '',
|
|
36
|
+
verifyButtonText = '',
|
|
37
|
+
organizationNumberLabel = '',
|
|
38
|
+
className = '',
|
|
39
|
+
}) => {
|
|
40
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
41
|
+
const [apiErrorMsg, setApiErrorMsg] = useState<string>('');
|
|
42
|
+
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
43
|
+
|
|
44
|
+
const methods = useForm<EHFFormInputsType>({
|
|
45
|
+
defaultValues: {
|
|
46
|
+
...initialData,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const {
|
|
51
|
+
handleSubmit,
|
|
52
|
+
formState: { errors },
|
|
53
|
+
} = methods;
|
|
54
|
+
|
|
55
|
+
const onSubmit: SubmitHandler<EHFFormInputsType> = async (
|
|
56
|
+
data
|
|
57
|
+
): Promise<void> => {
|
|
58
|
+
setApiErrorMsg('');
|
|
59
|
+
setErrorsMsg([]);
|
|
60
|
+
setLoading(true);
|
|
61
|
+
try {
|
|
62
|
+
await invoiceLookup({
|
|
63
|
+
network: InvoiceLookupNetworkEnum.EHF,
|
|
64
|
+
value: data.organizationNumber,
|
|
65
|
+
});
|
|
66
|
+
callback(data.organizationNumber);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
setApiErrorMsg(prepareErrorMessage(error as Error));
|
|
69
|
+
setErrorsMsg(
|
|
70
|
+
prepareErrorsArrayMessage(
|
|
71
|
+
(
|
|
72
|
+
error as {
|
|
73
|
+
errors: ErrorsMsg;
|
|
74
|
+
}
|
|
75
|
+
)?.errors
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
} finally {
|
|
79
|
+
setLoading(false);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const handleBack = () => {
|
|
84
|
+
onBack?.();
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<FormProvider {...methods}>
|
|
89
|
+
<form
|
|
90
|
+
className={`${className}`}
|
|
91
|
+
onSubmit={handleSubmit(onSubmit)}
|
|
92
|
+
data-testid="ehf-form-id"
|
|
93
|
+
>
|
|
94
|
+
<InputField
|
|
95
|
+
name="organizationNumber"
|
|
96
|
+
label={organizationNumberLabel}
|
|
97
|
+
required
|
|
98
|
+
readOnly={false}
|
|
99
|
+
errors={errors}
|
|
100
|
+
/>
|
|
101
|
+
<div className="d-flex justify-center flex-wrap gap-2">
|
|
102
|
+
<Button
|
|
103
|
+
type="button"
|
|
104
|
+
btnType="default"
|
|
105
|
+
disable={loading}
|
|
106
|
+
buttonText={backButtonText}
|
|
107
|
+
onClick={handleBack}
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
<Button
|
|
111
|
+
type="submit"
|
|
112
|
+
loading={loading}
|
|
113
|
+
buttonText={verifyButtonText}
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
{apiErrorMsg && <Alert className="mt-2" msg={apiErrorMsg} />}
|
|
118
|
+
{errorsMsg?.length > 0 &&
|
|
119
|
+
errorsMsg.map((i) => <Alert className="mt-2" msg={i} />)}
|
|
120
|
+
</form>
|
|
121
|
+
</FormProvider>
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export default EHFForm;
|
|
@@ -10,13 +10,14 @@ type Props = {
|
|
|
10
10
|
label?: string;
|
|
11
11
|
errorReqMsg?: string;
|
|
12
12
|
errors?: {
|
|
13
|
-
|
|
13
|
+
[key: string]: {
|
|
14
14
|
message?: string;
|
|
15
15
|
};
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
const AddressField: FC<Props> = ({
|
|
20
|
+
name = 'address',
|
|
20
21
|
required = false,
|
|
21
22
|
readOnly = false,
|
|
22
23
|
label = 'Address',
|
|
@@ -33,17 +34,15 @@ const AddressField: FC<Props> = ({
|
|
|
33
34
|
placeholder=" "
|
|
34
35
|
readOnly={readOnly}
|
|
35
36
|
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
36
|
-
{...register(
|
|
37
|
+
{...register(name, {
|
|
37
38
|
required: required ? errorReqMsg : false,
|
|
38
39
|
})}
|
|
39
40
|
/>
|
|
40
41
|
<label className="label-control" htmlFor={id}>
|
|
41
42
|
{label} {required && <span className="text-error">*</span>}
|
|
42
43
|
</label>
|
|
43
|
-
{errors && errors
|
|
44
|
-
<div className="text-error caption">
|
|
45
|
-
{errors.address.message}
|
|
46
|
-
</div>
|
|
44
|
+
{errors && errors[name] && (
|
|
45
|
+
<div className="text-error caption">{errors[name].message}</div>
|
|
47
46
|
)}
|
|
48
47
|
</div>
|
|
49
48
|
);
|
|
@@ -11,13 +11,14 @@ type Props = {
|
|
|
11
11
|
errorReqMsg?: string;
|
|
12
12
|
errorInvalidEmailMsg?: string;
|
|
13
13
|
errors?: {
|
|
14
|
-
|
|
14
|
+
[key: string]: {
|
|
15
15
|
message?: string;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
const EmailField: FC<Props> = ({
|
|
21
|
+
name = 'email',
|
|
21
22
|
required = false,
|
|
22
23
|
readOnly = false,
|
|
23
24
|
label = 'Email',
|
|
@@ -36,7 +37,7 @@ const EmailField: FC<Props> = ({
|
|
|
36
37
|
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
37
38
|
readOnly={readOnly}
|
|
38
39
|
type="email"
|
|
39
|
-
{...register(
|
|
40
|
+
{...register(name, {
|
|
40
41
|
required: required ? errorReqMsg : false,
|
|
41
42
|
pattern: {
|
|
42
43
|
value: /^[-!#-'*+/-9=?^-~]+(?:\.[-!#-'*+/-9=?^-~]+)*@[-!#-'*+/-9=?^-~]+(?:\.[-!#-'*+/-9=?^-~]{2,20})+$/i,
|
|
@@ -47,8 +48,8 @@ const EmailField: FC<Props> = ({
|
|
|
47
48
|
<label className="label-control" htmlFor={id}>
|
|
48
49
|
{label} {required && <span className="text-error">*</span>}
|
|
49
50
|
</label>
|
|
50
|
-
{errors && errors
|
|
51
|
-
<div className="text-error caption">{errors.
|
|
51
|
+
{errors && errors[name] && (
|
|
52
|
+
<div className="text-error caption">{errors[name].message}</div>
|
|
52
53
|
)}
|
|
53
54
|
</div>
|
|
54
55
|
);
|
|
@@ -12,6 +12,15 @@ export const FIELD_TYPES = {
|
|
|
12
12
|
ORGANIZATION_NUMBER: 'organizationNumber',
|
|
13
13
|
BUYER_REFERENCE: 'buyerReference',
|
|
14
14
|
ORDER_REFERENCE: 'orderReference',
|
|
15
|
+
INVOICE_NAME: 'invoiceName',
|
|
16
|
+
INVOICE_ADDRESS: 'invoiceAddress',
|
|
17
|
+
INVOICE_CITY: 'invoiceCity',
|
|
18
|
+
INVOICE_ZIP: 'invoiceZip',
|
|
19
|
+
INVOICE_COUNTRY: 'invoiceCountry',
|
|
20
|
+
INVOICE_PHONE: 'invoicePhoneNumber',
|
|
21
|
+
INVOICE_EMAIL: 'invoiceEmail',
|
|
22
|
+
INVOICE_CARE_OF: 'invoiceCareOf',
|
|
23
|
+
INVOICE_BUYER_REFERENCE: 'invoiceBuyerReference',
|
|
15
24
|
};
|
|
16
25
|
|
|
17
26
|
export const DEFAULT_ORDER_FORM_FIELDS: OrderFormFiledType[] = [
|
|
@@ -18,6 +18,15 @@ const formFieldsMapper = {
|
|
|
18
18
|
[FIELD_TYPES.ORGANIZATION_NUMBER]: InputField,
|
|
19
19
|
[FIELD_TYPES.BUYER_REFERENCE]: InputField,
|
|
20
20
|
[FIELD_TYPES.ORDER_REFERENCE]: InputField,
|
|
21
|
+
[FIELD_TYPES.INVOICE_PHONE]: PhoneField,
|
|
22
|
+
[FIELD_TYPES.INVOICE_NAME]: NameField,
|
|
23
|
+
[FIELD_TYPES.INVOICE_EMAIL]: EmailField,
|
|
24
|
+
[FIELD_TYPES.INVOICE_ADDRESS]: AddressField,
|
|
25
|
+
[FIELD_TYPES.INVOICE_COUNTRY]: InputField,
|
|
26
|
+
[FIELD_TYPES.INVOICE_CITY]: InputField,
|
|
27
|
+
[FIELD_TYPES.INVOICE_ZIP]: InputField,
|
|
28
|
+
[FIELD_TYPES.INVOICE_CARE_OF]: InputField,
|
|
29
|
+
[FIELD_TYPES.INVOICE_BUYER_REFERENCE]: InputField,
|
|
21
30
|
};
|
|
22
31
|
|
|
23
32
|
export default formFieldsMapper;
|
|
@@ -10,13 +10,14 @@ type Props = {
|
|
|
10
10
|
label?: string;
|
|
11
11
|
errorReqMsg?: string;
|
|
12
12
|
errors?: {
|
|
13
|
-
|
|
13
|
+
[key: string]: {
|
|
14
14
|
message?: string;
|
|
15
15
|
};
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
const NameField: FC<Props> = ({
|
|
20
|
+
name = 'name',
|
|
20
21
|
required = false,
|
|
21
22
|
readOnly = false,
|
|
22
23
|
label = 'Name',
|
|
@@ -33,15 +34,15 @@ const NameField: FC<Props> = ({
|
|
|
33
34
|
placeholder=" "
|
|
34
35
|
readOnly={readOnly}
|
|
35
36
|
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
36
|
-
{...register(
|
|
37
|
+
{...register(name, {
|
|
37
38
|
required: required ? errorReqMsg : false,
|
|
38
39
|
})}
|
|
39
40
|
/>
|
|
40
41
|
<label className="label-control" htmlFor={id}>
|
|
41
42
|
{label} {required && <span className="text-error">*</span>}
|
|
42
43
|
</label>
|
|
43
|
-
{errors && errors
|
|
44
|
-
<div className="text-error caption">{errors
|
|
44
|
+
{errors && errors[name] && (
|
|
45
|
+
<div className="text-error caption">{errors[name].message}</div>
|
|
45
46
|
)}
|
|
46
47
|
</div>
|
|
47
48
|
);
|
|
@@ -11,13 +11,14 @@ type Props = {
|
|
|
11
11
|
errorReqMsg?: string;
|
|
12
12
|
errorInvalidPhoneMsg?: string;
|
|
13
13
|
errors?: {
|
|
14
|
-
|
|
14
|
+
[key: string]: {
|
|
15
15
|
message?: string;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
const PhoneFiled: FC<Props> = ({
|
|
21
|
+
name = 'phoneNumber',
|
|
21
22
|
required = false,
|
|
22
23
|
readOnly = false,
|
|
23
24
|
label = 'Phone number',
|
|
@@ -36,7 +37,7 @@ const PhoneFiled: FC<Props> = ({
|
|
|
36
37
|
placeholder=" "
|
|
37
38
|
readOnly={readOnly}
|
|
38
39
|
type="tel"
|
|
39
|
-
{...register(
|
|
40
|
+
{...register(name, {
|
|
40
41
|
required: required ? errorReqMsg : false,
|
|
41
42
|
pattern: {
|
|
42
43
|
value: /^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]{6,14}$/g,
|
|
@@ -47,10 +48,8 @@ const PhoneFiled: FC<Props> = ({
|
|
|
47
48
|
<label className="label-control" htmlFor={id}>
|
|
48
49
|
{label} {required && <span className="text-error">*</span>}
|
|
49
50
|
</label>
|
|
50
|
-
{errors && errors
|
|
51
|
-
<div className="text-error caption">
|
|
52
|
-
{errors.phoneNumber.message}
|
|
53
|
-
</div>
|
|
51
|
+
{errors && errors[name] && (
|
|
52
|
+
<div className="text-error caption">{errors[name].message}</div>
|
|
54
53
|
)}
|
|
55
54
|
</div>
|
|
56
55
|
);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { useFormContext } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
required?: boolean;
|
|
9
|
+
readOnly?: boolean;
|
|
10
|
+
label?: string;
|
|
11
|
+
errorReqMsg?: string;
|
|
12
|
+
errors?: {
|
|
13
|
+
[key: string]: {
|
|
14
|
+
message?: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const ToggleField: FC<Props> = ({
|
|
20
|
+
name,
|
|
21
|
+
required = false,
|
|
22
|
+
readOnly = false,
|
|
23
|
+
label = '',
|
|
24
|
+
errorReqMsg = 'This field is required!',
|
|
25
|
+
errors,
|
|
26
|
+
}) => {
|
|
27
|
+
const { register } = useFormContext();
|
|
28
|
+
const id = uuidv4();
|
|
29
|
+
return (
|
|
30
|
+
<div className="field-wrapper">
|
|
31
|
+
<div className="d-flex align-center flex-wrap">
|
|
32
|
+
<label className="sdk-on-off-label" htmlFor={id}>
|
|
33
|
+
{label} {required && <span className="text-error">*</span>}
|
|
34
|
+
</label>
|
|
35
|
+
<label
|
|
36
|
+
className="sdk-on-off"
|
|
37
|
+
data-testid={`sdk-${name}-field-id`}
|
|
38
|
+
>
|
|
39
|
+
<input
|
|
40
|
+
id={id}
|
|
41
|
+
type="checkbox"
|
|
42
|
+
readOnly={readOnly}
|
|
43
|
+
className={`${readOnly ? 'read-only' : ''}`}
|
|
44
|
+
{...register(name, {
|
|
45
|
+
required: required ? errorReqMsg : false,
|
|
46
|
+
})}
|
|
47
|
+
/>
|
|
48
|
+
<span className="slider round"></span>
|
|
49
|
+
</label>
|
|
50
|
+
</div>
|
|
51
|
+
{errors && errors[name] && (
|
|
52
|
+
<div className="text-error caption">{errors[name].message}</div>
|
|
53
|
+
)}
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default ToggleField;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { FC, useState } from 'react';
|
|
2
|
+
import { FormProvider, useForm, SubmitHandler } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { invoiceLookup } from '../../api/InvoiceApi';
|
|
5
|
+
import Alert from '../Alert/Alert';
|
|
6
|
+
import Button from '../Button/Button';
|
|
7
|
+
import InputField from '../FormFields/InputField';
|
|
8
|
+
import {
|
|
9
|
+
prepareErrorMessage,
|
|
10
|
+
prepareErrorsArrayMessage,
|
|
11
|
+
} from '../../utils/helper';
|
|
12
|
+
import { InvoiceLookupNetworkEnum } from '../../enums/general';
|
|
13
|
+
import { ErrorsMsg } from '../../types/general';
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
callback: (value: string) => void;
|
|
17
|
+
onBack: () => void;
|
|
18
|
+
backButtonText?: string;
|
|
19
|
+
verifyButtonText?: string;
|
|
20
|
+
organizationNumberLabel?: string;
|
|
21
|
+
glnLabel?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type OIOFormInputsType = {
|
|
26
|
+
cvr: string;
|
|
27
|
+
gln: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const initialData = {
|
|
31
|
+
cvr: '',
|
|
32
|
+
gln: '',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const EHFForm: FC<Props> = ({
|
|
36
|
+
callback,
|
|
37
|
+
onBack,
|
|
38
|
+
backButtonText = '',
|
|
39
|
+
verifyButtonText = '',
|
|
40
|
+
organizationNumberLabel = '',
|
|
41
|
+
glnLabel = '',
|
|
42
|
+
className = '',
|
|
43
|
+
}) => {
|
|
44
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
45
|
+
const [apiErrorMsg, setApiErrorMsg] = useState<string>('');
|
|
46
|
+
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
47
|
+
|
|
48
|
+
const methods = useForm<OIOFormInputsType>({
|
|
49
|
+
defaultValues: {
|
|
50
|
+
...initialData,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
handleSubmit,
|
|
56
|
+
watch,
|
|
57
|
+
formState: { errors },
|
|
58
|
+
} = methods;
|
|
59
|
+
|
|
60
|
+
const cvr = watch('cvr');
|
|
61
|
+
const gln = watch('gln');
|
|
62
|
+
|
|
63
|
+
const onSubmit: SubmitHandler<OIOFormInputsType> = async (
|
|
64
|
+
data
|
|
65
|
+
): Promise<void> => {
|
|
66
|
+
setApiErrorMsg('');
|
|
67
|
+
setErrorsMsg([]);
|
|
68
|
+
setLoading(true);
|
|
69
|
+
try {
|
|
70
|
+
await invoiceLookup({
|
|
71
|
+
network: data.gln
|
|
72
|
+
? InvoiceLookupNetworkEnum.OIO_GLN
|
|
73
|
+
: InvoiceLookupNetworkEnum.OIO_Danish_CVR,
|
|
74
|
+
value: data.gln || data.cvr,
|
|
75
|
+
});
|
|
76
|
+
callback(data.gln || data.cvr);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
setApiErrorMsg(prepareErrorMessage(error as Error));
|
|
79
|
+
setErrorsMsg(
|
|
80
|
+
prepareErrorsArrayMessage(
|
|
81
|
+
(
|
|
82
|
+
error as {
|
|
83
|
+
errors: ErrorsMsg;
|
|
84
|
+
}
|
|
85
|
+
)?.errors
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
} finally {
|
|
89
|
+
setLoading(false);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const handleBack = () => {
|
|
94
|
+
onBack?.();
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<FormProvider {...methods}>
|
|
99
|
+
<form
|
|
100
|
+
className={`${className}`}
|
|
101
|
+
onSubmit={handleSubmit(onSubmit)}
|
|
102
|
+
data-testid="oio-form-id"
|
|
103
|
+
>
|
|
104
|
+
<InputField
|
|
105
|
+
name="cvr"
|
|
106
|
+
label={organizationNumberLabel}
|
|
107
|
+
required={!gln}
|
|
108
|
+
readOnly={false}
|
|
109
|
+
errors={errors}
|
|
110
|
+
/>
|
|
111
|
+
<InputField
|
|
112
|
+
name="gln"
|
|
113
|
+
label={glnLabel}
|
|
114
|
+
required={!cvr}
|
|
115
|
+
readOnly={false}
|
|
116
|
+
errors={errors}
|
|
117
|
+
/>
|
|
118
|
+
<div className="d-flex justify-center flex-wrap gap-2">
|
|
119
|
+
<Button
|
|
120
|
+
type="button"
|
|
121
|
+
btnType="default"
|
|
122
|
+
disable={loading}
|
|
123
|
+
buttonText={backButtonText}
|
|
124
|
+
onClick={handleBack}
|
|
125
|
+
/>
|
|
126
|
+
|
|
127
|
+
<Button
|
|
128
|
+
type="submit"
|
|
129
|
+
loading={loading}
|
|
130
|
+
buttonText={verifyButtonText}
|
|
131
|
+
/>
|
|
132
|
+
</div>
|
|
133
|
+
{apiErrorMsg && <Alert className="mt-2" msg={apiErrorMsg} />}
|
|
134
|
+
{errorsMsg?.length > 0 &&
|
|
135
|
+
errorsMsg.map((i) => <Alert className="mt-2" msg={i} />)}
|
|
136
|
+
</form>
|
|
137
|
+
</FormProvider>
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export default EHFForm;
|
|
@@ -7,6 +7,7 @@ import { PaymentMethodEnum } from '../../enums/general';
|
|
|
7
7
|
import { WRONG_MSG, PAYMENT_METHOD_DEFAULT } from '../../constants/index';
|
|
8
8
|
import Alert from '../Alert/Alert';
|
|
9
9
|
import Button from '../Button/Button';
|
|
10
|
+
import ToggleField from '../FormFields/ToggleFiled';
|
|
10
11
|
import formFieldsMapper from '../FormFields/FormFieldsMapper';
|
|
11
12
|
import { DEFAULT_ORDER_FORM_FIELDS } from '../FormFields/FormFields.helper';
|
|
12
13
|
import { OrderFormInputsType, OrderInfoType } from '../../types/order';
|
|
@@ -16,8 +17,10 @@ import {
|
|
|
16
17
|
ErrorsMsg,
|
|
17
18
|
} from '../../types/general';
|
|
18
19
|
import {
|
|
20
|
+
orderInvoiceContactFields,
|
|
19
21
|
prepareAgreementModel,
|
|
20
22
|
prepareContactModel,
|
|
23
|
+
prepareInvoiceModel,
|
|
21
24
|
} from '../../utils/order.helper';
|
|
22
25
|
import {
|
|
23
26
|
prepareErrorMessage,
|
|
@@ -40,14 +43,20 @@ type Props = {
|
|
|
40
43
|
paymentMethodsOptions?: PaymentMethodOptionsType;
|
|
41
44
|
defaultValues?: OrderFormInputsType;
|
|
42
45
|
paymentMethods?: { label: string; value: PaymentMethodEnum }[];
|
|
43
|
-
|
|
46
|
+
submitButtonText?: string;
|
|
44
47
|
paymentMethodLabel?: string;
|
|
45
48
|
errorReqMsg?: string;
|
|
46
49
|
errorInvalidEmailMsg?: string;
|
|
47
50
|
errorInvalidPhoneMsg?: string;
|
|
51
|
+
invoiceAddressSelection?: {
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
label?: string;
|
|
54
|
+
fields?: OrderFormFiledType[];
|
|
55
|
+
};
|
|
48
56
|
};
|
|
49
57
|
|
|
50
58
|
const initialData = {
|
|
59
|
+
invoiceAddressSelection: false,
|
|
51
60
|
name: '',
|
|
52
61
|
email: '',
|
|
53
62
|
phoneNumber: '',
|
|
@@ -56,6 +65,7 @@ const initialData = {
|
|
|
56
65
|
address: '',
|
|
57
66
|
zip: '',
|
|
58
67
|
paymentMethod: PAYMENT_METHOD_DEFAULT,
|
|
68
|
+
orderReference: '',
|
|
59
69
|
};
|
|
60
70
|
|
|
61
71
|
const OrderForm: FC<Props> = ({
|
|
@@ -72,7 +82,8 @@ const OrderForm: FC<Props> = ({
|
|
|
72
82
|
language,
|
|
73
83
|
merchantAgreementUrl,
|
|
74
84
|
paymentMethods = [],
|
|
75
|
-
|
|
85
|
+
invoiceAddressSelection,
|
|
86
|
+
submitButtonText = 'Start',
|
|
76
87
|
paymentMethodLabel = 'Select Payment Method',
|
|
77
88
|
errorReqMsg = '',
|
|
78
89
|
errorInvalidEmailMsg = '',
|
|
@@ -95,14 +106,19 @@ const OrderForm: FC<Props> = ({
|
|
|
95
106
|
defaultValues?.paymentMethod || PAYMENT_METHOD_DEFAULT,
|
|
96
107
|
},
|
|
97
108
|
});
|
|
109
|
+
const invoiceOrderFields =
|
|
110
|
+
invoiceAddressSelection?.fields || orderInvoiceContactFields;
|
|
98
111
|
|
|
99
112
|
const {
|
|
100
113
|
register,
|
|
101
114
|
handleSubmit,
|
|
102
115
|
setValue,
|
|
116
|
+
watch,
|
|
103
117
|
formState: { errors },
|
|
104
118
|
} = methods;
|
|
105
119
|
|
|
120
|
+
const invoiceAddressToggle = watch('invoiceAddressSelection');
|
|
121
|
+
|
|
106
122
|
const onSubmit: SubmitHandler<OrderFormInputsType> = async (
|
|
107
123
|
data
|
|
108
124
|
): Promise<void> => {
|
|
@@ -158,6 +174,13 @@ const OrderForm: FC<Props> = ({
|
|
|
158
174
|
templateSubscriptionPlanId: templatePackageId,
|
|
159
175
|
},
|
|
160
176
|
paymentAgreement: { ...agreements },
|
|
177
|
+
invoiceContact: invoiceAddressToggle
|
|
178
|
+
? prepareInvoiceModel({
|
|
179
|
+
data,
|
|
180
|
+
orderFields: invoiceOrderFields,
|
|
181
|
+
})
|
|
182
|
+
: undefined,
|
|
183
|
+
orderReference: data.orderReference || undefined,
|
|
161
184
|
});
|
|
162
185
|
callback(responseOrder.terminalRedirectUrl, {
|
|
163
186
|
orderId: responseOrder.id,
|
|
@@ -256,10 +279,39 @@ const OrderForm: FC<Props> = ({
|
|
|
256
279
|
})}
|
|
257
280
|
</Suspense>
|
|
258
281
|
)}
|
|
282
|
+
{invoiceAddressSelection?.enabled && (
|
|
283
|
+
<ToggleField
|
|
284
|
+
name="invoiceAddressSelection"
|
|
285
|
+
label={
|
|
286
|
+
invoiceAddressSelection?.label ?? 'Invoice Address'
|
|
287
|
+
}
|
|
288
|
+
/>
|
|
289
|
+
)}
|
|
290
|
+
{invoiceAddressToggle && invoiceOrderFields?.length > 0 && (
|
|
291
|
+
<Suspense fallback={null}>
|
|
292
|
+
{invoiceOrderFields.map((field) => {
|
|
293
|
+
const Component = formFieldsMapper[field.name];
|
|
294
|
+
|
|
295
|
+
return Component ? (
|
|
296
|
+
<Component
|
|
297
|
+
key={field.name}
|
|
298
|
+
name={field.name}
|
|
299
|
+
label={field.label}
|
|
300
|
+
required={field.required || false}
|
|
301
|
+
readOnly={field.readOnly || false}
|
|
302
|
+
errors={errors}
|
|
303
|
+
errorReqMsg={errorReqMsg}
|
|
304
|
+
errorInvalidEmailMsg={errorInvalidEmailMsg}
|
|
305
|
+
errorInvalidPhoneMsg={errorInvalidPhoneMsg}
|
|
306
|
+
/>
|
|
307
|
+
) : null;
|
|
308
|
+
})}
|
|
309
|
+
</Suspense>
|
|
310
|
+
)}
|
|
259
311
|
<Button
|
|
260
312
|
type="submit"
|
|
261
313
|
loading={loading}
|
|
262
|
-
buttonText={
|
|
314
|
+
buttonText={submitButtonText}
|
|
263
315
|
/>
|
|
264
316
|
<Alert className="mt-2" msg={apiErrorMsg} />
|
|
265
317
|
{errorsMsg?.length > 0 &&
|
package/src/enums/general.ts
CHANGED
|
@@ -16,3 +16,15 @@ export enum MessageEventTypeEnum {
|
|
|
16
16
|
CANCEL = 'cancel',
|
|
17
17
|
COMPLETE = 'complete',
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
export enum InvoiceLookupNetworkEnum {
|
|
21
|
+
EHF = '0192',
|
|
22
|
+
OIO_GLN = '0088',
|
|
23
|
+
OIO_Danish_CVR = '0096',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export enum FormTypeEnum {
|
|
27
|
+
ORDER = 'order',
|
|
28
|
+
EHF = 'EHF',
|
|
29
|
+
OIO = 'OIO',
|
|
30
|
+
}
|
package/src/types/api.ts
CHANGED
package/src/types/general.ts
CHANGED
|
@@ -38,10 +38,19 @@ export type ConfigType = {
|
|
|
38
38
|
paymentMethodsOptions?: PaymentMethodOptionsType;
|
|
39
39
|
language?: string;
|
|
40
40
|
merchantAgreementUrl?: string;
|
|
41
|
+
invoiceAddressSelection?: {
|
|
42
|
+
enabled?: boolean;
|
|
43
|
+
label?: string;
|
|
44
|
+
fields?: OrderFormFiledType[];
|
|
45
|
+
};
|
|
41
46
|
settings?: {
|
|
42
47
|
successText?: string;
|
|
43
48
|
failureText?: string;
|
|
44
|
-
|
|
49
|
+
submitButtonText?: string;
|
|
50
|
+
backButtonText?: string;
|
|
51
|
+
verifyButtonText?: string;
|
|
52
|
+
organizationNumberLabel?: string;
|
|
53
|
+
glnLabel?: string;
|
|
45
54
|
orderDefaultValues?: OrderFormInputsType;
|
|
46
55
|
paymentMethodLabel?: string;
|
|
47
56
|
errorReqMsg?: string;
|
package/src/types/order.ts
CHANGED
|
@@ -10,6 +10,17 @@ export type OrderFormInputsType = {
|
|
|
10
10
|
address?: string;
|
|
11
11
|
zip?: string;
|
|
12
12
|
careOf?: string;
|
|
13
|
+
invoiceAddressSelection?: boolean;
|
|
14
|
+
orderReference?: string;
|
|
15
|
+
invoiceName?: string;
|
|
16
|
+
invoiceEmail?: string;
|
|
17
|
+
invoicePhoneNumber?: string;
|
|
18
|
+
invoiceCountry?: string;
|
|
19
|
+
invoiceCity?: string;
|
|
20
|
+
invoiceAddress?: string;
|
|
21
|
+
invoiceZip?: string;
|
|
22
|
+
invoiceCareOf?: string;
|
|
23
|
+
invoiceBuyerReference?: string;
|
|
13
24
|
};
|
|
14
25
|
|
|
15
26
|
export type VippsMobilePay = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MessageEventTypeEnum, PaymentMethodEnum } from '../enums/general';
|
|
2
2
|
import { AgreementsType, OrderFormInputsType } from '../types/order';
|
|
3
3
|
import { OrderFormFiledType } from '../types/general';
|
|
4
|
+
import { FIELD_TYPES } from '../components/FormFields/FormFields.helper';
|
|
4
5
|
|
|
5
6
|
type AgreementModelType = {
|
|
6
7
|
paymentMethod: PaymentMethodEnum;
|
|
@@ -112,9 +113,111 @@ export const prepareContactModel = ({
|
|
|
112
113
|
? data.zip?.trim() || undefined
|
|
113
114
|
: undefined,
|
|
114
115
|
careOf: orderFields.find((i) => i.name === 'careOf')
|
|
115
|
-
? data.
|
|
116
|
+
? data.careOf?.trim() || undefined
|
|
116
117
|
: undefined,
|
|
117
118
|
};
|
|
118
119
|
|
|
119
120
|
return model;
|
|
120
121
|
};
|
|
122
|
+
|
|
123
|
+
export const prepareInvoiceModel = ({
|
|
124
|
+
data,
|
|
125
|
+
orderFields,
|
|
126
|
+
}: ContactModelType) => {
|
|
127
|
+
const model = {
|
|
128
|
+
name: orderFields.find((i) => i.name === 'invoiceName')
|
|
129
|
+
? data.invoiceName?.trim() || undefined
|
|
130
|
+
: undefined,
|
|
131
|
+
email: orderFields.find((i) => i.name === 'invoiceEmail')
|
|
132
|
+
? data.invoiceEmail?.trim() || undefined
|
|
133
|
+
: undefined,
|
|
134
|
+
phone: orderFields.find((i) => i.name === 'invoicePhoneNumber')
|
|
135
|
+
? data.invoicePhoneNumber?.trim() || undefined
|
|
136
|
+
: undefined,
|
|
137
|
+
country: orderFields.find((i) => i.name === 'invoiceCountry')
|
|
138
|
+
? data.invoiceCountry?.trim() || undefined
|
|
139
|
+
: undefined,
|
|
140
|
+
city: orderFields.find((i) => i.name === 'invoiceCity')
|
|
141
|
+
? data.invoiceCity?.trim() || undefined
|
|
142
|
+
: undefined,
|
|
143
|
+
addressLines: orderFields.find((i) => i.name === 'invoiceAddress')
|
|
144
|
+
? data.invoiceAddress?.trim()
|
|
145
|
+
? data.invoiceAddress
|
|
146
|
+
?.trim()
|
|
147
|
+
.replace(/\r\n/g, '\n')
|
|
148
|
+
.split('\n')
|
|
149
|
+
.filter((line) => line)
|
|
150
|
+
: undefined
|
|
151
|
+
: undefined,
|
|
152
|
+
zip: orderFields.find((i) => i.name === 'invoiceZip')
|
|
153
|
+
? data.invoiceZip?.trim() || undefined
|
|
154
|
+
: undefined,
|
|
155
|
+
careOf: orderFields.find((i) => i.name === 'invoiceCareOf')
|
|
156
|
+
? data.invoiceCareOf?.trim() || undefined
|
|
157
|
+
: undefined,
|
|
158
|
+
buyerReference: orderFields.find(
|
|
159
|
+
(i) => i.name === 'invoiceBuyerReference'
|
|
160
|
+
)
|
|
161
|
+
? data.invoiceBuyerReference?.trim() || undefined
|
|
162
|
+
: undefined,
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
return model;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const orderInvoiceContactFields = [
|
|
169
|
+
{
|
|
170
|
+
name: FIELD_TYPES.INVOICE_NAME,
|
|
171
|
+
label: 'Name',
|
|
172
|
+
required: false,
|
|
173
|
+
readOnly: false,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: FIELD_TYPES.INVOICE_EMAIL,
|
|
177
|
+
label: 'Email',
|
|
178
|
+
required: false,
|
|
179
|
+
readOnly: false,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: FIELD_TYPES.INVOICE_PHONE,
|
|
183
|
+
label: 'Phone',
|
|
184
|
+
required: false,
|
|
185
|
+
readOnly: false,
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: FIELD_TYPES.INVOICE_COUNTRY,
|
|
189
|
+
label: 'Country',
|
|
190
|
+
required: false,
|
|
191
|
+
readOnly: false,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: FIELD_TYPES.INVOICE_CITY,
|
|
195
|
+
label: 'City',
|
|
196
|
+
required: false,
|
|
197
|
+
readOnly: false,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: FIELD_TYPES.INVOICE_ADDRESS,
|
|
201
|
+
label: 'Address',
|
|
202
|
+
required: false,
|
|
203
|
+
readOnly: false,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: FIELD_TYPES.INVOICE_ZIP,
|
|
207
|
+
label: 'Zip',
|
|
208
|
+
required: false,
|
|
209
|
+
readOnly: false,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: FIELD_TYPES.INVOICE_CARE_OF,
|
|
213
|
+
label: 'Contact Person',
|
|
214
|
+
required: false,
|
|
215
|
+
readOnly: false,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: FIELD_TYPES.INVOICE_BUYER_REFERENCE,
|
|
219
|
+
label: 'Buyer Reference',
|
|
220
|
+
required: false,
|
|
221
|
+
readOnly: false,
|
|
222
|
+
},
|
|
223
|
+
];
|