@zeniai/client-epic-state 5.1.4 → 5.1.5-betaML1
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/lib/entity/company/companyPayload.d.ts +4 -0
- package/lib/entity/company/companyPayload.js +6 -0
- package/lib/entity/company/companyStateTypes.d.ts +7 -0
- package/lib/entity/paymentAccount/paymentAccountSelector.d.ts +1 -0
- package/lib/entity/paymentAccount/paymentAccountSelector.js +9 -0
- package/lib/entity/tenant/epic/deleteConnectionEpic.d.ts +1 -1
- package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.d.ts +21 -0
- package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.js +59 -0
- package/lib/entity/tenant/epic/saveAPIKeyConnectionEpic.d.ts +1 -1
- package/lib/entity/tenant/epic/saveConnectorCredentialsEpic.d.ts +3 -3
- package/lib/entity/tenant/epic/saveOAuthConnectionEpic.d.ts +1 -1
- package/lib/entity/tenant/tenantPayload.d.ts +1 -0
- package/lib/entity/tenant/tenantReducer.d.ts +38 -25
- package/lib/entity/tenant/tenantReducer.js +65 -5
- package/lib/entity/tenant/tenantState.d.ts +1 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +2 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.js +1 -0
- package/lib/entity/transaction/stateTypes/transaction.d.ts +2 -0
- package/lib/epic.d.ts +6 -1
- package/lib/epic.js +7 -1
- package/lib/esm/entity/company/companyPayload.js +6 -0
- package/lib/esm/entity/paymentAccount/paymentAccountSelector.js +8 -0
- package/lib/esm/entity/tenant/epic/initEmailConnectOAuthEpic.js +55 -0
- package/lib/esm/entity/tenant/tenantReducer.js +63 -3
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +1 -0
- package/lib/esm/epic.js +7 -1
- package/lib/esm/index.js +11 -7
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/backgroundRefetchReviewTabEpic.js +7 -1
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +1 -1
- package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +1 -0
- package/lib/esm/view/fileView/epic/deleteFileEpic.js +2 -2
- package/lib/esm/view/fileView/epic/deleteFileListEpic.js +2 -2
- package/lib/esm/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +40 -0
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.js +29 -0
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +40 -0
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +24 -18
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.js +29 -17
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +223 -51
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewSelector.js +24 -12
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewState.js +37 -6
- package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +58 -0
- package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +77 -0
- package/lib/esm/view/spendManagement/commonSetup/kycKybAutofillActions.js +14 -0
- package/lib/esm/view/spendManagement/commonSetup/kycKybParseMapper.js +207 -0
- package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +106 -52
- package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +6 -1
- package/lib/esm/view/spendManagement/commonSetup/types/kycKybAutofill.js +41 -0
- package/lib/index.d.ts +14 -10
- package/lib/index.js +64 -35
- package/lib/view/expenseAutomationView/epics/transactionCategorization/backgroundRefetchReviewTabEpic.js +7 -1
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +1 -1
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +1 -0
- package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +2 -0
- package/lib/view/fileView/epic/deleteFileEpic.js +1 -1
- package/lib/view/fileView/epic/deleteFileListEpic.js +1 -1
- package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.d.ts +7 -0
- package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +44 -0
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.d.ts +8 -0
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.js +33 -0
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.d.ts +9 -0
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +44 -0
- package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewEpic.js +24 -18
- package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.d.ts +2 -2
- package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.js +27 -15
- package/lib/view/onboardingView/customerView/onboardingCustomerViewPayload.d.ts +3 -0
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +44 -5
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +225 -52
- package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.d.ts +6 -1
- package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.js +27 -12
- package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +52 -8
- package/lib/view/onboardingView/customerView/onboardingCustomerViewState.js +39 -7
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.d.ts +28 -0
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +62 -0
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.d.ts +9 -0
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +81 -0
- package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.d.ts +24 -0
- package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.js +17 -0
- package/lib/view/spendManagement/commonSetup/kycKybParseMapper.d.ts +29 -0
- package/lib/view/spendManagement/commonSetup/kycKybParseMapper.js +215 -0
- package/lib/view/spendManagement/commonSetup/setupViewReducer.d.ts +28 -2
- package/lib/view/spendManagement/commonSetup/setupViewReducer.js +107 -53
- package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +7 -2
- package/lib/view/spendManagement/commonSetup/setupViewSelector.js +6 -1
- package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +19 -0
- package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.d.ts +154 -0
- package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.js +46 -0
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { date } from '../../../zeniDayJS';
|
|
3
|
+
import { parseUploadedKybDocument, parseUploadedKybDocumentFailure, parseUploadedKycDocument, parseUploadedKycDocumentFailure, } from '../../spendManagement/commonSetup/kycKybAutofillActions';
|
|
4
|
+
import { emptyAiAgentsActivationSubview, } from './onboardingCustomerViewState';
|
|
3
5
|
const initialStatus = {
|
|
4
6
|
fetchState: 'Not-Started',
|
|
5
7
|
error: undefined,
|
|
@@ -8,62 +10,33 @@ export const initialState = {
|
|
|
8
10
|
updateStatus: initialStatus,
|
|
9
11
|
saveStatus: initialStatus,
|
|
10
12
|
dashboardLoadedStatus: initialStatus,
|
|
11
|
-
currentStep: '
|
|
13
|
+
currentStep: 'setup_billing',
|
|
14
|
+
currentSubStep: 'default',
|
|
15
|
+
parsingDocumentFileIds: [],
|
|
12
16
|
companyDetails: {
|
|
17
|
+
autoFilledFields: [],
|
|
13
18
|
localData: undefined,
|
|
14
19
|
},
|
|
15
|
-
companyOfficerUpdateStatus: {
|
|
16
|
-
|
|
20
|
+
companyOfficerUpdateStatus: (() => {
|
|
21
|
+
const emptyOfficerSlot = {
|
|
22
|
+
autoFilledFields: [],
|
|
17
23
|
localData: undefined,
|
|
18
24
|
sendOtpStatus: initialStatus,
|
|
19
25
|
otpverificationStatus: initialStatus,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
otpverificationStatus: initialStatus,
|
|
35
|
-
},
|
|
36
|
-
Officer_5: {
|
|
37
|
-
localData: undefined,
|
|
38
|
-
sendOtpStatus: initialStatus,
|
|
39
|
-
otpverificationStatus: initialStatus,
|
|
40
|
-
},
|
|
41
|
-
Officer_6: {
|
|
42
|
-
localData: undefined,
|
|
43
|
-
sendOtpStatus: initialStatus,
|
|
44
|
-
otpverificationStatus: initialStatus,
|
|
45
|
-
},
|
|
46
|
-
Officer_7: {
|
|
47
|
-
localData: undefined,
|
|
48
|
-
sendOtpStatus: initialStatus,
|
|
49
|
-
otpverificationStatus: initialStatus,
|
|
50
|
-
},
|
|
51
|
-
Officer_8: {
|
|
52
|
-
localData: undefined,
|
|
53
|
-
sendOtpStatus: initialStatus,
|
|
54
|
-
otpverificationStatus: initialStatus,
|
|
55
|
-
},
|
|
56
|
-
Officer_9: {
|
|
57
|
-
localData: undefined,
|
|
58
|
-
sendOtpStatus: initialStatus,
|
|
59
|
-
otpverificationStatus: initialStatus,
|
|
60
|
-
},
|
|
61
|
-
Officer_10: {
|
|
62
|
-
localData: undefined,
|
|
63
|
-
sendOtpStatus: initialStatus,
|
|
64
|
-
otpverificationStatus: initialStatus,
|
|
65
|
-
},
|
|
66
|
-
},
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
Officer_1: { ...emptyOfficerSlot },
|
|
29
|
+
Officer_2: { ...emptyOfficerSlot },
|
|
30
|
+
Officer_3: { ...emptyOfficerSlot },
|
|
31
|
+
Officer_4: { ...emptyOfficerSlot },
|
|
32
|
+
Officer_5: { ...emptyOfficerSlot },
|
|
33
|
+
Officer_6: { ...emptyOfficerSlot },
|
|
34
|
+
Officer_7: { ...emptyOfficerSlot },
|
|
35
|
+
Officer_8: { ...emptyOfficerSlot },
|
|
36
|
+
Officer_9: { ...emptyOfficerSlot },
|
|
37
|
+
Officer_10: { ...emptyOfficerSlot },
|
|
38
|
+
};
|
|
39
|
+
})(),
|
|
67
40
|
primaryContactDetails: {},
|
|
68
41
|
paymentAccountDetails: {
|
|
69
42
|
fetchStatus: initialStatus,
|
|
@@ -91,6 +64,7 @@ export const initialState = {
|
|
|
91
64
|
},
|
|
92
65
|
fetchState: 'Not-Started',
|
|
93
66
|
error: undefined,
|
|
67
|
+
aiAgentsActivation: { ...emptyAiAgentsActivationSubview },
|
|
94
68
|
uiState: {
|
|
95
69
|
isQBOPopupOpen: false,
|
|
96
70
|
isCardPaymentPopupOpen: false,
|
|
@@ -143,6 +117,9 @@ const onboardingCustomerView = createSlice({
|
|
|
143
117
|
updateCurrentStep(draft, action) {
|
|
144
118
|
draft.currentStep = action.payload.step;
|
|
145
119
|
},
|
|
120
|
+
updateCurrentSubStep(draft, action) {
|
|
121
|
+
draft.currentSubStep = action.payload.subStep;
|
|
122
|
+
},
|
|
146
123
|
updateOnboardingCustomerViewAccountDetails: {
|
|
147
124
|
prepare(paymentAccountIds, subscriptionPaymentAccountIds) {
|
|
148
125
|
return { payload: { paymentAccountIds, subscriptionPaymentAccountIds } };
|
|
@@ -180,6 +157,126 @@ const onboardingCustomerView = createSlice({
|
|
|
180
157
|
};
|
|
181
158
|
},
|
|
182
159
|
},
|
|
160
|
+
acknowledgeOnboardingAiFinanceTeam: {
|
|
161
|
+
reducer(draft) {
|
|
162
|
+
draft.aiFinanceTeamAcknowledgementStatus = {
|
|
163
|
+
fetchState: 'In-Progress',
|
|
164
|
+
error: undefined,
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
prepare(companyId) {
|
|
168
|
+
return {
|
|
169
|
+
payload: { companyId },
|
|
170
|
+
};
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
acknowledgeOnboardingAiFinanceTeamSuccess(draft) {
|
|
174
|
+
draft.aiFinanceTeamAcknowledgementStatus = {
|
|
175
|
+
fetchState: 'Completed',
|
|
176
|
+
error: undefined,
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
acknowledgeOnboardingAiFinanceTeamFailure: {
|
|
180
|
+
reducer(draft, action) {
|
|
181
|
+
draft.aiFinanceTeamAcknowledgementStatus = {
|
|
182
|
+
fetchState: 'Error',
|
|
183
|
+
error: action.payload,
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
prepare(error) {
|
|
187
|
+
return {
|
|
188
|
+
payload: error,
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
acknowledgeOnboardingAiActivationViewed: {
|
|
193
|
+
reducer(draft) {
|
|
194
|
+
draft.aiActivationViewedAcknowledgementStatus = {
|
|
195
|
+
fetchState: 'In-Progress',
|
|
196
|
+
error: undefined,
|
|
197
|
+
};
|
|
198
|
+
},
|
|
199
|
+
prepare(companyId) {
|
|
200
|
+
return {
|
|
201
|
+
payload: { companyId },
|
|
202
|
+
};
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
acknowledgeOnboardingAiActivationViewedSuccess(draft) {
|
|
206
|
+
draft.aiActivationViewedAcknowledgementStatus = {
|
|
207
|
+
fetchState: 'Completed',
|
|
208
|
+
error: undefined,
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
acknowledgeOnboardingAiActivationViewedFailure: {
|
|
212
|
+
reducer(draft, action) {
|
|
213
|
+
draft.aiActivationViewedAcknowledgementStatus = {
|
|
214
|
+
fetchState: 'Error',
|
|
215
|
+
error: action.payload,
|
|
216
|
+
};
|
|
217
|
+
},
|
|
218
|
+
prepare(error) {
|
|
219
|
+
return {
|
|
220
|
+
payload: error,
|
|
221
|
+
};
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
fetchAiAgentsActivationStatus(draft) {
|
|
225
|
+
draft.aiAgentsActivation.fetchStatus = {
|
|
226
|
+
fetchState: 'In-Progress',
|
|
227
|
+
error: undefined,
|
|
228
|
+
};
|
|
229
|
+
},
|
|
230
|
+
fetchAiAgentsActivationStatusSuccess: {
|
|
231
|
+
reducer(draft, action) {
|
|
232
|
+
draft.aiAgentsActivation.fetchStatus = {
|
|
233
|
+
fetchState: 'Completed',
|
|
234
|
+
error: undefined,
|
|
235
|
+
};
|
|
236
|
+
draft.aiAgentsActivation.phases = action.payload.phases;
|
|
237
|
+
draft.aiAgentsActivation.counts = action.payload.counts;
|
|
238
|
+
},
|
|
239
|
+
prepare(payload) {
|
|
240
|
+
return { payload };
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
fetchAiAgentsActivationStatusFailure: {
|
|
244
|
+
reducer(draft, action) {
|
|
245
|
+
draft.aiAgentsActivation.fetchStatus = {
|
|
246
|
+
fetchState: 'Error',
|
|
247
|
+
error: action.payload,
|
|
248
|
+
};
|
|
249
|
+
},
|
|
250
|
+
prepare(error) {
|
|
251
|
+
return { payload: error };
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
aiAgentsActivationCountsUpdated: {
|
|
255
|
+
reducer(draft, action) {
|
|
256
|
+
draft.aiAgentsActivation.counts = {
|
|
257
|
+
...draft.aiAgentsActivation.counts,
|
|
258
|
+
...action.payload,
|
|
259
|
+
};
|
|
260
|
+
},
|
|
261
|
+
prepare(payload) {
|
|
262
|
+
return { payload };
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
aiAgentsActivationPhaseChanged: {
|
|
266
|
+
reducer(draft, action) {
|
|
267
|
+
const target = draft.aiAgentsActivation.phases;
|
|
268
|
+
const index = target.findIndex((phase) => phase.key === action.payload.key);
|
|
269
|
+
if (index === -1) {
|
|
270
|
+
target.push(action.payload);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
target[index] = { ...target[index], ...action.payload };
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
prepare(payload) {
|
|
277
|
+
return { payload };
|
|
278
|
+
},
|
|
279
|
+
},
|
|
183
280
|
updateOnboardingCustomerViewDashboardLoaded: {
|
|
184
281
|
reducer(draft) {
|
|
185
282
|
draft.dashboardLoadedStatus = {
|
|
@@ -592,7 +689,82 @@ const onboardingCustomerView = createSlice({
|
|
|
592
689
|
clearOnboardingCustomerView(draft) {
|
|
593
690
|
Object.assign(draft, initialState);
|
|
594
691
|
},
|
|
692
|
+
/** Merge AI-parsed officer fields into the officer's onboarding localData. */
|
|
693
|
+
applyKycDocumentAutofillForOnboarding: {
|
|
694
|
+
reducer(draft, action) {
|
|
695
|
+
const { officerType, values, autoFilledFieldNames, fileId } = action.payload;
|
|
696
|
+
const slot = draft.companyOfficerUpdateStatus[officerType];
|
|
697
|
+
slot.localData = Object.assign({}, slot.localData, values);
|
|
698
|
+
slot.autoFilledFields = Array.from(new Set([...(slot.autoFilledFields ?? []), ...autoFilledFieldNames]));
|
|
699
|
+
draft.parsingDocumentFileIds = (draft.parsingDocumentFileIds ?? []).filter((id) => id !== fileId);
|
|
700
|
+
},
|
|
701
|
+
prepare(payload) {
|
|
702
|
+
return { payload };
|
|
703
|
+
},
|
|
704
|
+
},
|
|
705
|
+
/** Merge AI-parsed company fields into companyDetails onboarding localData. */
|
|
706
|
+
applyKybDocumentAutofillForOnboarding: {
|
|
707
|
+
reducer(draft, action) {
|
|
708
|
+
const { values, autoFilledFieldNames, fileId } = action.payload;
|
|
709
|
+
draft.companyDetails.localData = Object.assign({}, draft.companyDetails.localData, values);
|
|
710
|
+
const prev = draft.companyDetails.autoFilledFields ?? [];
|
|
711
|
+
draft.companyDetails.autoFilledFields = Array.from(new Set([...prev, ...autoFilledFieldNames]));
|
|
712
|
+
draft.parsingDocumentFileIds = (draft.parsingDocumentFileIds ?? []).filter((id) => id !== fileId);
|
|
713
|
+
},
|
|
714
|
+
prepare(payload) {
|
|
715
|
+
return { payload };
|
|
716
|
+
},
|
|
717
|
+
},
|
|
718
|
+
/** Wipe AI-autofill badges during onboarding. */
|
|
719
|
+
clearKycKybAutofillForOnboarding: {
|
|
720
|
+
reducer(draft, action) {
|
|
721
|
+
const { officerType } = action.payload;
|
|
722
|
+
if (officerType != null) {
|
|
723
|
+
draft.companyOfficerUpdateStatus[officerType].autoFilledFields = [];
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
draft.companyDetails.autoFilledFields = [];
|
|
727
|
+
Object.keys(draft.companyOfficerUpdateStatus).forEach((key) => {
|
|
728
|
+
draft.companyOfficerUpdateStatus[key].autoFilledFields = [];
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
},
|
|
732
|
+
prepare(payload = {}) {
|
|
733
|
+
return { payload };
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
extraReducers: (builder) => {
|
|
738
|
+
const addParsingFileId = (draft, fileId) => {
|
|
739
|
+
draft.parsingDocumentFileIds = draft.parsingDocumentFileIds ?? [];
|
|
740
|
+
if (!draft.parsingDocumentFileIds.includes(fileId)) {
|
|
741
|
+
draft.parsingDocumentFileIds.push(fileId);
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
const removeParsingFileId = (draft, fileId) => {
|
|
745
|
+
draft.parsingDocumentFileIds = (draft.parsingDocumentFileIds ?? []).filter((id) => id !== fileId);
|
|
746
|
+
};
|
|
747
|
+
builder.addCase(parseUploadedKycDocument, (draft, action) => {
|
|
748
|
+
if (action.payload.target === 'onboarding') {
|
|
749
|
+
addParsingFileId(draft, action.payload.fileId);
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
builder.addCase(parseUploadedKybDocument, (draft, action) => {
|
|
753
|
+
if (action.payload.target === 'onboarding') {
|
|
754
|
+
addParsingFileId(draft, action.payload.fileId);
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
builder.addCase(parseUploadedKycDocumentFailure, (draft, action) => {
|
|
758
|
+
if (action.payload.target === 'onboarding') {
|
|
759
|
+
removeParsingFileId(draft, action.payload.fileId);
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
builder.addCase(parseUploadedKybDocumentFailure, (draft, action) => {
|
|
763
|
+
if (action.payload.target === 'onboarding') {
|
|
764
|
+
removeParsingFileId(draft, action.payload.fileId);
|
|
765
|
+
}
|
|
766
|
+
});
|
|
595
767
|
},
|
|
596
768
|
});
|
|
597
|
-
export const { fetchOnboardingCustomerView, fetchOnboardingCustomerSetupView, fetchOnboardingCustomerSetupViewSuccess, fetchOnboardingCustomerSetupViewFailure, updateOnboardingCustomerViewCompleteStatus, updateOnboardingCustomerViewCompleteStatusSuccess, updateOnboardingCustomerViewCompleteStatusFailure, updateOnboardingCustomerViewDashboardLoaded, updateOnboardingCustomerViewDashboardLoadedSuccess, updateOnboardingCustomerViewDashboardLoadedFailure, updateOnboardingCustomerView, updateOnboardingCustomerViewSuccess, updateOnboardingCustomerViewFailure, updateOnboardingPaymentAccountStatus, updateOnboardingPaymentAccountStatusSuccess, updateOnboardingPaymentAccountStatusFailure, updateOnboardingPaymentAccountLoginStatus, updateOnboardingPaymentAccountLoginStatusSuccess, updateOnboardingPaymentAccountLoginStatusFailure, establishOnboardingPlaidConnection, establishOnboardingPlaidConnectionSuccess, establishOnboardingPlaidConnectionFailure, getOnboardingPlaidLinkToken, getOnboardingPlaidLinkTokenSuccess, getOnboardingPlaidLinkTokenFailure, updateCurrentStep, updateOnboardingCustomerViewAccountDetails, updateOnboardingCustomerViewLocalStoreData, saveOnboardingCustomerViewDataInLocalStore, saveOnboardingCompnayOfficerPhoneInLocalStore, updateOnboardingCustomerViewUIState, sendOnboardingOfficerOtp, sendOnboardingOfficerOtpSuccess, sendOnboardingOfficerOtpFailure, resendOnboardingOfficerOtp, verifyOnboardingOfficerOtp, verifyOnboardingOfficerOtpSuccess, verifyOnboardingOfficerOtpFailure, clearOnboardingCustomerViewDataInLocalStore, clearOnboardingCustomerView, } = onboardingCustomerView.actions;
|
|
769
|
+
export const { fetchOnboardingCustomerView, fetchOnboardingCustomerSetupView, fetchOnboardingCustomerSetupViewSuccess, fetchOnboardingCustomerSetupViewFailure, updateOnboardingCustomerViewCompleteStatus, updateOnboardingCustomerViewCompleteStatusSuccess, updateOnboardingCustomerViewCompleteStatusFailure, acknowledgeOnboardingAiFinanceTeam, acknowledgeOnboardingAiFinanceTeamSuccess, acknowledgeOnboardingAiFinanceTeamFailure, acknowledgeOnboardingAiActivationViewed, acknowledgeOnboardingAiActivationViewedSuccess, acknowledgeOnboardingAiActivationViewedFailure, fetchAiAgentsActivationStatus, fetchAiAgentsActivationStatusSuccess, fetchAiAgentsActivationStatusFailure, aiAgentsActivationCountsUpdated, aiAgentsActivationPhaseChanged, updateOnboardingCustomerViewDashboardLoaded, updateOnboardingCustomerViewDashboardLoadedSuccess, updateOnboardingCustomerViewDashboardLoadedFailure, updateOnboardingCustomerView, updateOnboardingCustomerViewSuccess, updateOnboardingCustomerViewFailure, updateOnboardingPaymentAccountStatus, updateOnboardingPaymentAccountStatusSuccess, updateOnboardingPaymentAccountStatusFailure, updateOnboardingPaymentAccountLoginStatus, updateOnboardingPaymentAccountLoginStatusSuccess, updateOnboardingPaymentAccountLoginStatusFailure, establishOnboardingPlaidConnection, establishOnboardingPlaidConnectionSuccess, establishOnboardingPlaidConnectionFailure, getOnboardingPlaidLinkToken, getOnboardingPlaidLinkTokenSuccess, getOnboardingPlaidLinkTokenFailure, updateCurrentStep, updateCurrentSubStep, updateOnboardingCustomerViewAccountDetails, updateOnboardingCustomerViewLocalStoreData, saveOnboardingCustomerViewDataInLocalStore, saveOnboardingCompnayOfficerPhoneInLocalStore, updateOnboardingCustomerViewUIState, sendOnboardingOfficerOtp, sendOnboardingOfficerOtpSuccess, sendOnboardingOfficerOtpFailure, resendOnboardingOfficerOtp, verifyOnboardingOfficerOtp, verifyOnboardingOfficerOtpSuccess, verifyOnboardingOfficerOtpFailure, clearOnboardingCustomerViewDataInLocalStore, clearOnboardingCustomerView, applyKycDocumentAutofillForOnboarding, applyKybDocumentAutofillForOnboarding, clearKycKybAutofillForOnboarding, } = onboardingCustomerView.actions;
|
|
598
770
|
export default onboardingCustomerView.reducer;
|
|
@@ -8,10 +8,10 @@ import { getUserRoleByUserIds } from '../../../entity/userRole/userRoleSelector'
|
|
|
8
8
|
import { getCompanyConfig } from '../../companyConfigView/companyConfigSelector';
|
|
9
9
|
import { getCompanyView } from '../../companyView/selectorHelpers/getCompanyView';
|
|
10
10
|
import { getCompanyAndIdentityDetails, } from '../../spendManagement/commonSetup/setupViewSelector';
|
|
11
|
-
import { ALL_ONBOARDING_STEPS, ALL_ZENI_USER_ONBOARDING_STEPS, REQUIRED_ONBOARDING_STEPS, ZENI_USER_REQUIRED_ONBOARDING_STEPS, toOnboardingStepType, } from './onboardingCustomerViewState';
|
|
11
|
+
import { ALL_ONBOARDING_STEPS, ALL_ZENI_USER_ONBOARDING_STEPS, REQUIRED_ONBOARDING_STEPS, ZENI_USER_REQUIRED_ONBOARDING_STEPS, emptyAiAgentsActivationSubview, toOnboardingStepType, } from './onboardingCustomerViewState';
|
|
12
12
|
export function getOnboardingCustomerView(state, companyId) {
|
|
13
13
|
const { fileState, paymentAccountState, onboardingCustomerViewState, userState, userRoleState, subscriptionPaymentAccountState, companyConfigState, cardPaymentViewState, countryListState, addressViewState, } = state;
|
|
14
|
-
const { companyDetails, companyOfficerUpdateStatus, primaryContactDetails, subscriptionPaymentAccountIds, paymentAccountDetails, plaidConnectionDetails, updateStatus, saveStatus, currentStep, uiState, fetchState, error, } = onboardingCustomerViewState;
|
|
14
|
+
const { companyDetails, companyOfficerUpdateStatus, primaryContactDetails, subscriptionPaymentAccountIds, paymentAccountDetails, plaidConnectionDetails, parsingDocumentFileIds, updateStatus, saveStatus, currentStep, currentSubStep, uiState, fetchState, error, } = onboardingCustomerViewState;
|
|
15
15
|
const { paymentAccountIds } = paymentAccountDetails;
|
|
16
16
|
let subscriptionPaymentAccount;
|
|
17
17
|
let paymentAccount;
|
|
@@ -54,6 +54,7 @@ export function getOnboardingCustomerView(state, companyId) {
|
|
|
54
54
|
companyDetails,
|
|
55
55
|
companyOfficerUpdateStatus,
|
|
56
56
|
primaryContactDetails,
|
|
57
|
+
parsingDocumentFileIds,
|
|
57
58
|
});
|
|
58
59
|
const companyAddress = addressViewState.newAddressState?.company_address;
|
|
59
60
|
if (companyAddress == null &&
|
|
@@ -73,7 +74,7 @@ export function getOnboardingCustomerView(state, companyId) {
|
|
|
73
74
|
cardPaymentViewState.cardPaymentsIds.length > 0) &&
|
|
74
75
|
companyView?.company.company.companyOnboardingInfo
|
|
75
76
|
.subscriptionBillingAddressId != null) {
|
|
76
|
-
completedSteps.push('
|
|
77
|
+
completedSteps.push('setup_billing');
|
|
77
78
|
}
|
|
78
79
|
const isPaymentVerified = (paymentAccount?.providerVerificationStatus?.code?.includes('verified') ===
|
|
79
80
|
true &&
|
|
@@ -84,24 +85,25 @@ export function getOnboardingCustomerView(state, companyId) {
|
|
|
84
85
|
.subscriptionBillingAddressId != null;
|
|
85
86
|
if ((isPaymentVerified || hasSubscriptionBillingAddress) &&
|
|
86
87
|
!(isPaymentVerified && hasSubscriptionBillingAddress)) {
|
|
87
|
-
halfCompletedSteps.push('
|
|
88
|
+
halfCompletedSteps.push('setup_billing');
|
|
88
89
|
}
|
|
89
90
|
const isValidConnection = externalConnections?.accounting[0]?.isValid ?? false;
|
|
90
91
|
if (isValidConnection) {
|
|
91
|
-
completedSteps.push('
|
|
92
|
+
completedSteps.push('connect_ledger');
|
|
92
93
|
}
|
|
93
|
-
|
|
94
|
+
const isCompanyDetailsDone = companyDetails.localData != null &&
|
|
94
95
|
primaryContactDetails.localData != null &&
|
|
95
|
-
isCompanyDetailsCompleted(fileState, companyView, primaryContact)
|
|
96
|
-
completedSteps.push('company_details');
|
|
97
|
-
}
|
|
96
|
+
isCompanyDetailsCompleted(fileState, companyView, primaryContact);
|
|
98
97
|
const officerIndex = companyOfficers.length > 0
|
|
99
98
|
? Object.values(companyOfficerLocalData).findIndex((officer) => officer?.isSelectedForVerification === true)
|
|
100
99
|
: 0;
|
|
101
100
|
const selectedOfficerType = `Officer_${officerIndex < 0 ? 1 : officerIndex + 1}`;
|
|
102
|
-
|
|
103
|
-
isOfficerDetailsCompleted(companyOfficers, companyOfficerRoles, companyOfficerLocalData[selectedOfficerType], fileState)
|
|
104
|
-
|
|
101
|
+
const isOfficerDone = companyOfficerLocalData[selectedOfficerType] != null &&
|
|
102
|
+
isOfficerDetailsCompleted(companyOfficers, companyOfficerRoles, companyOfficerLocalData[selectedOfficerType], fileState);
|
|
103
|
+
// The verification step (single sidebar step) is only "complete" once both
|
|
104
|
+
// the company-officer and company-details sub-steps are fully filled in.
|
|
105
|
+
if (isCompanyDetailsDone && isOfficerDone) {
|
|
106
|
+
completedSteps.push('verification');
|
|
105
107
|
}
|
|
106
108
|
const { allStepsData, requiredStepsData } = onboardingStepsData(isValidConnection, currentTenant?.productSettings ?? [], accountingConnectionCreationMode);
|
|
107
109
|
const allRequiredStepsCompleted = requiredStepsData.every((step) => {
|
|
@@ -119,6 +121,7 @@ export function getOnboardingCustomerView(state, companyId) {
|
|
|
119
121
|
return {
|
|
120
122
|
companyDetailsLocalData,
|
|
121
123
|
companyOfficerLocalData,
|
|
124
|
+
parsingDocumentFileIds,
|
|
122
125
|
subscriptionBillingAddress: subscriptionBillingAddress?.addressToCreate,
|
|
123
126
|
companyView,
|
|
124
127
|
allNationalityCountries,
|
|
@@ -127,6 +130,7 @@ export function getOnboardingCustomerView(state, companyId) {
|
|
|
127
130
|
officer: isOfficerDetailsSavePending(companyOfficers, companyOfficerRoles, fileState, companyOfficerLocalData[selectedOfficerType]),
|
|
128
131
|
},
|
|
129
132
|
currentStep,
|
|
133
|
+
currentSubStep,
|
|
130
134
|
completedSteps,
|
|
131
135
|
halfCompletedSteps,
|
|
132
136
|
allRequiredStepsCompleted,
|
|
@@ -323,3 +327,11 @@ export const getProductSettingsString = (productSettings) => {
|
|
|
323
327
|
.map((key) => productKeyMap[key])
|
|
324
328
|
.join(',');
|
|
325
329
|
};
|
|
330
|
+
const fromActivationView = (state) =>
|
|
331
|
+
// Fall back to the empty subview so state hydrated from an older persisted
|
|
332
|
+
// version (before aiAgentsActivation existed) doesn't crash on .phases/.counts.
|
|
333
|
+
state.onboardingCustomerViewState.aiAgentsActivation ??
|
|
334
|
+
emptyAiAgentsActivationSubview;
|
|
335
|
+
export const getAiAgentsActivationSubview = (state) => fromActivationView(state);
|
|
336
|
+
export const getAiAgentsActivationPhases = (state) => fromActivationView(state).phases;
|
|
337
|
+
export const getAiAgentsActivationCounts = (state) => fromActivationView(state).counts;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { stringToUnion } from '../../../commonStateTypes/stringToUnion';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
// Onboarding steps are the 4 top-level surfaces. Officer + details verification
|
|
3
|
+
// live as sub-steps under `verification` (state machine in CustomerOnboardingPage).
|
|
4
|
+
// The optional data-source step is its own surface; the legacy connect-data-source
|
|
5
|
+
// sub-step under the old `qbo_connection` no longer exists.
|
|
6
|
+
export const ZENI_USER_REQUIRED_ONBOARDING_STEPS = ['setup_billing'];
|
|
5
7
|
export const CUSTOMER_REQUIRED_ONBOARDING_STEPS_WITH_QBO = [
|
|
6
|
-
'
|
|
8
|
+
'connect_ledger',
|
|
7
9
|
];
|
|
8
10
|
export const REQUIRED_ONBOARDING_STEPS = [
|
|
9
11
|
...ZENI_USER_REQUIRED_ONBOARDING_STEPS,
|
|
10
12
|
...CUSTOMER_REQUIRED_ONBOARDING_STEPS_WITH_QBO,
|
|
11
13
|
];
|
|
12
14
|
export const ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT = [
|
|
13
|
-
'
|
|
14
|
-
'company_details',
|
|
15
|
+
'verification',
|
|
15
16
|
];
|
|
16
17
|
export const ALL_ZENI_USER_ONBOARDING_STEPS = [
|
|
17
18
|
...ZENI_USER_REQUIRED_ONBOARDING_STEPS,
|
|
@@ -19,10 +20,40 @@ export const ALL_ZENI_USER_ONBOARDING_STEPS = [
|
|
|
19
20
|
];
|
|
20
21
|
export const ALL_CUSTOMER_ONBOARDING_STEPS_WITH_QBO = [
|
|
21
22
|
...CUSTOMER_REQUIRED_ONBOARDING_STEPS_WITH_QBO,
|
|
23
|
+
'connect_data_source',
|
|
22
24
|
...ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT,
|
|
23
25
|
];
|
|
24
26
|
export const ALL_ONBOARDING_STEPS = [
|
|
25
27
|
...REQUIRED_ONBOARDING_STEPS,
|
|
28
|
+
'connect_data_source',
|
|
26
29
|
...ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT,
|
|
27
30
|
];
|
|
28
31
|
export const toOnboardingStepType = (v) => stringToUnion(v, ALL_ONBOARDING_STEPS);
|
|
32
|
+
// Per-step sub-state. Lives in Redux so the save epic can tell, for example,
|
|
33
|
+
// an officer-form save from a company-details save while both share
|
|
34
|
+
// currentStep = 'verification'.
|
|
35
|
+
// - 'default' generic landing sub-state.
|
|
36
|
+
// - 'ai-activating' connect_ledger interstitial during AI activation.
|
|
37
|
+
// - 'unlock-stack' verification landing — VerifyUnlockFinancialStackPage.
|
|
38
|
+
// - 'company_officer' verification → officer form.
|
|
39
|
+
// - 'company_details' verification → company details form.
|
|
40
|
+
export const ALL_ONBOARDING_SUB_STEPS = [
|
|
41
|
+
'default',
|
|
42
|
+
'ai-activating',
|
|
43
|
+
'unlock-stack',
|
|
44
|
+
'company_officer',
|
|
45
|
+
'company_details',
|
|
46
|
+
];
|
|
47
|
+
export const toOnboardingSubStepType = (v) => stringToUnion(v, ALL_ONBOARDING_SUB_STEPS);
|
|
48
|
+
export const emptyAiAgentsActivationCounts = {
|
|
49
|
+
customerCount: 0,
|
|
50
|
+
glAccountCount: 0,
|
|
51
|
+
targetTransactionCount: 0,
|
|
52
|
+
transactionCount: 0,
|
|
53
|
+
vendorCount: 0,
|
|
54
|
+
};
|
|
55
|
+
export const emptyAiAgentsActivationSubview = {
|
|
56
|
+
counts: emptyAiAgentsActivationCounts,
|
|
57
|
+
fetchStatus: { fetchState: 'Not-Started', error: undefined },
|
|
58
|
+
phases: [],
|
|
59
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { isSuccessResponse } from '../../../../../responsePayload';
|
|
4
|
+
import { applyKybDocumentAutofillForOnboarding } from '../../../../onboardingView/customerView/onboardingCustomerViewReducer';
|
|
5
|
+
import { parseUploadedKybDocument, parseUploadedKybDocumentFailure, } from '../../kycKybAutofillActions';
|
|
6
|
+
import { mapCoiToCompanyDetails, mapTaxEinToCompanyDetails, } from '../../kycKybParseMapper';
|
|
7
|
+
import { applyKybDocumentAutofillForSetup } from '../../setupViewReducer';
|
|
8
|
+
const PROCESS_DOCUMENT_SYNC_PATH = '/1.0/documents/process/sync';
|
|
9
|
+
export const parseUploadedKybDocumentEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(parseUploadedKybDocument.match), mergeMap((action) => {
|
|
10
|
+
const { target, companyId, fileId, documentType } = action.payload;
|
|
11
|
+
const url = `${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}${PROCESS_DOCUMENT_SYNC_PATH}`;
|
|
12
|
+
const requestPayload = {
|
|
13
|
+
provided_document_type: documentType,
|
|
14
|
+
files: [{ file_id: fileId }],
|
|
15
|
+
processing_priority: 10,
|
|
16
|
+
metadata: { source: 'kyc_kyb_autofill' },
|
|
17
|
+
};
|
|
18
|
+
const failureAction = parseUploadedKybDocumentFailure({ target, fileId });
|
|
19
|
+
return zeniAPI
|
|
20
|
+
.postAndGetJSON(url, requestPayload)
|
|
21
|
+
.pipe(mergeMap((response) => {
|
|
22
|
+
if (!isSuccessResponse(response) || response.data == null) {
|
|
23
|
+
return of(failureAction);
|
|
24
|
+
}
|
|
25
|
+
// Sync API returns a batch envelope: `data.files[0].extracted_data`
|
|
26
|
+
// is the parser payload; `data` itself is the request-level wrapper.
|
|
27
|
+
const extracted = response.data.files?.[0]?.extracted_data;
|
|
28
|
+
if (extracted == null) {
|
|
29
|
+
return of(failureAction);
|
|
30
|
+
}
|
|
31
|
+
let result;
|
|
32
|
+
switch (documentType) {
|
|
33
|
+
case 'certificate_of_incorporation':
|
|
34
|
+
result = mapCoiToCompanyDetails(extracted);
|
|
35
|
+
break;
|
|
36
|
+
case 'tax_ein':
|
|
37
|
+
result = mapTaxEinToCompanyDetails(extracted);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
if (result.autoFilledFieldNames.length === 0) {
|
|
41
|
+
return of(failureAction);
|
|
42
|
+
}
|
|
43
|
+
const applyAction = target === 'setup'
|
|
44
|
+
? applyKybDocumentAutofillForSetup({
|
|
45
|
+
companyId,
|
|
46
|
+
fileId,
|
|
47
|
+
values: result.values,
|
|
48
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
49
|
+
})
|
|
50
|
+
: applyKybDocumentAutofillForOnboarding({
|
|
51
|
+
companyId,
|
|
52
|
+
fileId,
|
|
53
|
+
values: result.values,
|
|
54
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
55
|
+
});
|
|
56
|
+
return of(applyAction);
|
|
57
|
+
}), catchError(() => of(failureAction)));
|
|
58
|
+
}));
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { from, of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { isSuccessResponse } from '../../../../../responsePayload';
|
|
4
|
+
import { newAddressInLocalStore } from '../../../../addressView/addressViewReducer';
|
|
5
|
+
import { applyKycDocumentAutofillForOnboarding } from '../../../../onboardingView/customerView/onboardingCustomerViewReducer';
|
|
6
|
+
import { parseUploadedKycDocument, parseUploadedKycDocumentFailure, } from '../../kycKybAutofillActions';
|
|
7
|
+
import { mapDrivingLicenseToOfficer, mapPassportToOfficer, mapSsnCardToOfficer, } from '../../kycKybParseMapper';
|
|
8
|
+
import { applyKycDocumentAutofillForSetup } from '../../setupViewReducer';
|
|
9
|
+
const PROCESS_DOCUMENT_SYNC_PATH = '/1.0/documents/process/sync';
|
|
10
|
+
export const parseUploadedKycDocumentEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(parseUploadedKycDocument.match), mergeMap((action) => {
|
|
11
|
+
const { target, companyId, officerType, fileId, documentType } = action.payload;
|
|
12
|
+
const url = `${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}${PROCESS_DOCUMENT_SYNC_PATH}`;
|
|
13
|
+
const requestPayload = {
|
|
14
|
+
provided_document_type: documentType,
|
|
15
|
+
files: [{ file_id: fileId }],
|
|
16
|
+
processing_priority: 10,
|
|
17
|
+
metadata: { source: 'kyc_kyb_autofill' },
|
|
18
|
+
};
|
|
19
|
+
const failureAction = parseUploadedKycDocumentFailure({ target, fileId });
|
|
20
|
+
return zeniAPI
|
|
21
|
+
.postAndGetJSON(url, requestPayload)
|
|
22
|
+
.pipe(mergeMap((response) => {
|
|
23
|
+
if (!isSuccessResponse(response) || response.data == null) {
|
|
24
|
+
return of(failureAction);
|
|
25
|
+
}
|
|
26
|
+
// Sync API returns a batch envelope: `data.files[0].extracted_data`
|
|
27
|
+
// is the parser payload; `data` itself is the request-level wrapper
|
|
28
|
+
// ({request_id, status, files, metadata, ...}). Drill in before
|
|
29
|
+
// dispatching to the mapper.
|
|
30
|
+
const extracted = response.data.files?.[0]?.extracted_data;
|
|
31
|
+
if (extracted == null) {
|
|
32
|
+
return of(failureAction);
|
|
33
|
+
}
|
|
34
|
+
let result;
|
|
35
|
+
switch (documentType) {
|
|
36
|
+
case 'passport':
|
|
37
|
+
result = mapPassportToOfficer(extracted);
|
|
38
|
+
break;
|
|
39
|
+
case 'driving_license':
|
|
40
|
+
result = mapDrivingLicenseToOfficer(extracted);
|
|
41
|
+
break;
|
|
42
|
+
case 'social_security_card':
|
|
43
|
+
result = mapSsnCardToOfficer(extracted);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
if (result.autoFilledFieldNames.length === 0) {
|
|
47
|
+
return of(failureAction);
|
|
48
|
+
}
|
|
49
|
+
const applyAction = target === 'setup'
|
|
50
|
+
? applyKycDocumentAutofillForSetup({
|
|
51
|
+
companyId,
|
|
52
|
+
officerType,
|
|
53
|
+
fileId,
|
|
54
|
+
values: result.values,
|
|
55
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
56
|
+
})
|
|
57
|
+
: applyKycDocumentAutofillForOnboarding({
|
|
58
|
+
companyId,
|
|
59
|
+
officerType,
|
|
60
|
+
fileId,
|
|
61
|
+
values: result.values,
|
|
62
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
63
|
+
});
|
|
64
|
+
const actions = [applyAction];
|
|
65
|
+
// Driving licenses also carry the home address, which lives in the
|
|
66
|
+
// addressView slice (keyed `officer_<n>_address`). Seed it so the
|
|
67
|
+
// section's address field + ✦ badge pick it up.
|
|
68
|
+
if (result.address != null) {
|
|
69
|
+
const addressType = `${officerType.toLowerCase()}_address`;
|
|
70
|
+
actions.push(newAddressInLocalStore({
|
|
71
|
+
addressType,
|
|
72
|
+
addressToCreate: result.address,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
return from(actions);
|
|
76
|
+
}), catchError(() => of(failureAction)));
|
|
77
|
+
}));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trigger actions for the KYC / KYB autofill epics.
|
|
3
|
+
*
|
|
4
|
+
* These actions don't mutate state — the epic listens for them, calls
|
|
5
|
+
* document-communication-agent's sync endpoint, and dispatches the appropriate
|
|
6
|
+
* `applyKyc/KybDocumentAutofillFor{Setup,Onboarding}` against the matching
|
|
7
|
+
* slice. Co-located with the rest of the commonSetup module because the entire
|
|
8
|
+
* autofill flow is auxiliary to the setup view; there is no separate state.
|
|
9
|
+
*/
|
|
10
|
+
import { createAction } from '@reduxjs/toolkit';
|
|
11
|
+
export const parseUploadedKycDocument = createAction('commonSetup/parseUploadedKycDocument');
|
|
12
|
+
export const parseUploadedKybDocument = createAction('commonSetup/parseUploadedKybDocument');
|
|
13
|
+
export const parseUploadedKycDocumentFailure = createAction('commonSetup/parseUploadedKycDocumentFailure');
|
|
14
|
+
export const parseUploadedKybDocumentFailure = createAction('commonSetup/parseUploadedKybDocumentFailure');
|