@zeniai/client-epic-state 5.0.84 → 5.0.85-beta0ND
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/commonStateTypes/animations.d.ts +1 -1
- package/lib/commonStateTypes/animations.js +1 -0
- package/lib/entity/company/companyPayload.d.ts +2 -0
- package/lib/entity/company/companyPayload.js +2 -0
- package/lib/entity/company/companyStateTypes.d.ts +2 -0
- package/lib/entity/paymentAccount/paymentAccountSelector.d.ts +1 -0
- package/lib/entity/paymentAccount/paymentAccountSelector.js +4 -0
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -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 +54 -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 +19 -0
- package/lib/entity/tenant/tenantReducer.d.ts +49 -28
- package/lib/entity/tenant/tenantReducer.js +111 -5
- package/lib/entity/tenant/tenantState.d.ts +21 -0
- package/lib/epic.d.ts +8 -2
- package/lib/epic.js +9 -2
- package/lib/esm/commonStateTypes/animations.js +1 -0
- package/lib/esm/entity/company/companyPayload.js +2 -0
- package/lib/esm/entity/paymentAccount/paymentAccountSelector.js +3 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/esm/entity/tenant/epic/initEmailConnectOAuthEpic.js +50 -0
- package/lib/esm/entity/tenant/tenantReducer.js +108 -3
- package/lib/esm/epic.js +9 -2
- package/lib/esm/index.js +12 -9
- package/lib/esm/view/companyView/companyViewReducer.js +45 -1
- package/lib/esm/view/companyView/epic/companyPassport/dismissCapitalizationOnboardingEpic.js +25 -0
- package/lib/esm/view/companyView/epic/companyPassport/updateCapitalizationThresholdEpic.js +79 -0
- package/lib/esm/view/companyView/types/companyPassport/companyPassportViewState.js +4 -0
- package/lib/esm/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +45 -0
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +40 -0
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +168 -50
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewSelector.js +14 -0
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewState.js +13 -0
- package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +49 -0
- package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +58 -0
- package/lib/esm/view/spendManagement/commonSetup/kycKybAutofillActions.js +12 -0
- package/lib/esm/view/spendManagement/commonSetup/kycKybParseMapper.js +205 -0
- package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +71 -52
- package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +2 -0
- package/lib/esm/view/spendManagement/commonSetup/types/kycKybAutofill.js +28 -0
- package/lib/index.d.ts +15 -11
- package/lib/index.js +56 -34
- package/lib/view/companyView/companyViewReducer.d.ts +11 -1
- package/lib/view/companyView/companyViewReducer.js +47 -3
- package/lib/view/companyView/epic/companyPassport/dismissCapitalizationOnboardingEpic.d.ts +9 -0
- package/lib/view/companyView/epic/companyPassport/dismissCapitalizationOnboardingEpic.js +29 -0
- package/lib/view/companyView/epic/companyPassport/updateCapitalizationThresholdEpic.d.ts +10 -0
- package/lib/view/companyView/epic/companyPassport/updateCapitalizationThresholdEpic.js +83 -0
- package/lib/view/companyView/types/companyPassport/companyPassportViewState.d.ts +1 -0
- package/lib/view/companyView/types/companyPassport/companyPassportViewState.js +4 -0
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.d.ts +7 -0
- package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +49 -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/onboardingCustomerViewPayload.d.ts +3 -0
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +41 -4
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +170 -51
- package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.d.ts +7 -1
- package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.js +21 -1
- package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +37 -0
- package/lib/view/onboardingView/customerView/onboardingCustomerViewState.js +14 -1
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.d.ts +8 -0
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +53 -0
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.d.ts +8 -0
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +62 -0
- package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.d.ts +27 -0
- package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.js +15 -0
- package/lib/view/spendManagement/commonSetup/kycKybParseMapper.d.ts +24 -0
- package/lib/view/spendManagement/commonSetup/kycKybParseMapper.js +213 -0
- package/lib/view/spendManagement/commonSetup/setupViewReducer.d.ts +24 -2
- package/lib/view/spendManagement/commonSetup/setupViewReducer.js +72 -53
- package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +4 -0
- package/lib/view/spendManagement/commonSetup/setupViewSelector.js +2 -0
- package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +12 -0
- package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.d.ts +125 -0
- package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.js +32 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createSlice } from '@reduxjs/toolkit';
|
|
2
2
|
import { date } from '../../../zeniDayJS';
|
|
3
|
+
import { emptyAiAgentsActivationSubview, } from './onboardingCustomerViewState';
|
|
3
4
|
const initialStatus = {
|
|
4
5
|
fetchState: 'Not-Started',
|
|
5
6
|
error: undefined,
|
|
@@ -10,60 +11,29 @@ export const initialState = {
|
|
|
10
11
|
dashboardLoadedStatus: initialStatus,
|
|
11
12
|
currentStep: 'link_payment_account',
|
|
12
13
|
companyDetails: {
|
|
14
|
+
autoFilledFields: [],
|
|
13
15
|
localData: undefined,
|
|
14
16
|
},
|
|
15
|
-
companyOfficerUpdateStatus: {
|
|
16
|
-
|
|
17
|
+
companyOfficerUpdateStatus: (() => {
|
|
18
|
+
const emptyOfficerSlot = {
|
|
19
|
+
autoFilledFields: [],
|
|
17
20
|
localData: undefined,
|
|
18
21
|
sendOtpStatus: initialStatus,
|
|
19
22
|
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
|
-
},
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
Officer_1: { ...emptyOfficerSlot },
|
|
26
|
+
Officer_2: { ...emptyOfficerSlot },
|
|
27
|
+
Officer_3: { ...emptyOfficerSlot },
|
|
28
|
+
Officer_4: { ...emptyOfficerSlot },
|
|
29
|
+
Officer_5: { ...emptyOfficerSlot },
|
|
30
|
+
Officer_6: { ...emptyOfficerSlot },
|
|
31
|
+
Officer_7: { ...emptyOfficerSlot },
|
|
32
|
+
Officer_8: { ...emptyOfficerSlot },
|
|
33
|
+
Officer_9: { ...emptyOfficerSlot },
|
|
34
|
+
Officer_10: { ...emptyOfficerSlot },
|
|
35
|
+
};
|
|
36
|
+
})(),
|
|
67
37
|
primaryContactDetails: {},
|
|
68
38
|
paymentAccountDetails: {
|
|
69
39
|
fetchStatus: initialStatus,
|
|
@@ -91,6 +61,7 @@ export const initialState = {
|
|
|
91
61
|
},
|
|
92
62
|
fetchState: 'Not-Started',
|
|
93
63
|
error: undefined,
|
|
64
|
+
aiAgentsActivation: { ...emptyAiAgentsActivationSubview },
|
|
94
65
|
uiState: {
|
|
95
66
|
isQBOPopupOpen: false,
|
|
96
67
|
isCardPaymentPopupOpen: false,
|
|
@@ -180,6 +151,111 @@ const onboardingCustomerView = createSlice({
|
|
|
180
151
|
};
|
|
181
152
|
},
|
|
182
153
|
},
|
|
154
|
+
acknowledgeOnboardingAiFinanceTeam: {
|
|
155
|
+
reducer(draft) {
|
|
156
|
+
draft.aiFinanceTeamAcknowledgementStatus = {
|
|
157
|
+
fetchState: 'In-Progress',
|
|
158
|
+
error: undefined,
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
prepare(companyId) {
|
|
162
|
+
return {
|
|
163
|
+
payload: { companyId },
|
|
164
|
+
};
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
acknowledgeOnboardingAiFinanceTeamSuccess(draft) {
|
|
168
|
+
draft.aiFinanceTeamAcknowledgementStatus = {
|
|
169
|
+
fetchState: 'Completed',
|
|
170
|
+
error: undefined,
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
acknowledgeOnboardingAiFinanceTeamFailure: {
|
|
174
|
+
reducer(draft, action) {
|
|
175
|
+
draft.aiFinanceTeamAcknowledgementStatus = {
|
|
176
|
+
fetchState: 'Error',
|
|
177
|
+
error: action.payload,
|
|
178
|
+
};
|
|
179
|
+
},
|
|
180
|
+
prepare(error) {
|
|
181
|
+
return {
|
|
182
|
+
payload: error,
|
|
183
|
+
};
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
fetchAiAgentsActivationStatus(draft) {
|
|
187
|
+
draft.aiAgentsActivation.fetchStatus = {
|
|
188
|
+
fetchState: 'In-Progress',
|
|
189
|
+
error: undefined,
|
|
190
|
+
};
|
|
191
|
+
},
|
|
192
|
+
fetchAiAgentsActivationStatusSuccess: {
|
|
193
|
+
reducer(draft, action) {
|
|
194
|
+
draft.aiAgentsActivation.fetchStatus = {
|
|
195
|
+
fetchState: 'Completed',
|
|
196
|
+
error: undefined,
|
|
197
|
+
};
|
|
198
|
+
draft.aiAgentsActivation.ledgerPhases = action.payload.ledgerPhases;
|
|
199
|
+
draft.aiAgentsActivation.backgroundPhases =
|
|
200
|
+
action.payload.backgroundPhases;
|
|
201
|
+
draft.aiAgentsActivation.counts = action.payload.counts;
|
|
202
|
+
},
|
|
203
|
+
prepare(payload) {
|
|
204
|
+
return { payload };
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
fetchAiAgentsActivationStatusFailure: {
|
|
208
|
+
reducer(draft, action) {
|
|
209
|
+
draft.aiAgentsActivation.fetchStatus = {
|
|
210
|
+
fetchState: 'Error',
|
|
211
|
+
error: action.payload,
|
|
212
|
+
};
|
|
213
|
+
},
|
|
214
|
+
prepare(error) {
|
|
215
|
+
return { payload: error };
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
aiAgentsActivationCountsUpdated: {
|
|
219
|
+
reducer(draft, action) {
|
|
220
|
+
draft.aiAgentsActivation.counts = {
|
|
221
|
+
...draft.aiAgentsActivation.counts,
|
|
222
|
+
...action.payload,
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
prepare(payload) {
|
|
226
|
+
return { payload };
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
aiAgentsActivationPhaseChanged: {
|
|
230
|
+
reducer(draft, action) {
|
|
231
|
+
const target = action.payload.section === 'ledger'
|
|
232
|
+
? draft.aiAgentsActivation.ledgerPhases
|
|
233
|
+
: draft.aiAgentsActivation.backgroundPhases;
|
|
234
|
+
const index = target.findIndex((phase) => phase.key === action.payload.key);
|
|
235
|
+
if (index === -1) {
|
|
236
|
+
target.push(action.payload);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
target[index] = { ...target[index], ...action.payload };
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
prepare(payload) {
|
|
243
|
+
return { payload };
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
aiAgentsActivationSectionReady: {
|
|
247
|
+
reducer(draft, action) {
|
|
248
|
+
const target = action.payload.section === 'ledger'
|
|
249
|
+
? draft.aiAgentsActivation.ledgerPhases
|
|
250
|
+
: draft.aiAgentsActivation.backgroundPhases;
|
|
251
|
+
target.forEach((phase) => {
|
|
252
|
+
phase.status = 'ready';
|
|
253
|
+
});
|
|
254
|
+
},
|
|
255
|
+
prepare(payload) {
|
|
256
|
+
return { payload };
|
|
257
|
+
},
|
|
258
|
+
},
|
|
183
259
|
updateOnboardingCustomerViewDashboardLoaded: {
|
|
184
260
|
reducer(draft) {
|
|
185
261
|
draft.dashboardLoadedStatus = {
|
|
@@ -592,7 +668,49 @@ const onboardingCustomerView = createSlice({
|
|
|
592
668
|
clearOnboardingCustomerView(draft) {
|
|
593
669
|
Object.assign(draft, initialState);
|
|
594
670
|
},
|
|
671
|
+
/** Merge AI-parsed officer fields into the officer's onboarding localData. */
|
|
672
|
+
applyKycDocumentAutofillForOnboarding: {
|
|
673
|
+
reducer(draft, action) {
|
|
674
|
+
const { officerType, values, autoFilledFieldNames } = action.payload;
|
|
675
|
+
const slot = draft.companyOfficerUpdateStatus[officerType];
|
|
676
|
+
slot.localData = Object.assign({}, slot.localData, values);
|
|
677
|
+
slot.autoFilledFields = Array.from(new Set([...slot.autoFilledFields, ...autoFilledFieldNames]));
|
|
678
|
+
},
|
|
679
|
+
prepare(payload) {
|
|
680
|
+
return { payload };
|
|
681
|
+
},
|
|
682
|
+
},
|
|
683
|
+
/** Merge AI-parsed company fields into companyDetails onboarding localData. */
|
|
684
|
+
applyKybDocumentAutofillForOnboarding: {
|
|
685
|
+
reducer(draft, action) {
|
|
686
|
+
const { values, autoFilledFieldNames } = action.payload;
|
|
687
|
+
draft.companyDetails.localData = Object.assign({}, draft.companyDetails.localData, values);
|
|
688
|
+
const prev = draft.companyDetails.autoFilledFields ?? [];
|
|
689
|
+
draft.companyDetails.autoFilledFields = Array.from(new Set([...prev, ...autoFilledFieldNames]));
|
|
690
|
+
},
|
|
691
|
+
prepare(payload) {
|
|
692
|
+
return { payload };
|
|
693
|
+
},
|
|
694
|
+
},
|
|
695
|
+
/** Wipe AI-autofill badges during onboarding. */
|
|
696
|
+
clearKycKybAutofillForOnboarding: {
|
|
697
|
+
reducer(draft, action) {
|
|
698
|
+
const { officerType } = action.payload;
|
|
699
|
+
if (officerType != null) {
|
|
700
|
+
draft.companyOfficerUpdateStatus[officerType].autoFilledFields = [];
|
|
701
|
+
}
|
|
702
|
+
else {
|
|
703
|
+
draft.companyDetails.autoFilledFields = [];
|
|
704
|
+
Object.keys(draft.companyOfficerUpdateStatus).forEach((key) => {
|
|
705
|
+
draft.companyOfficerUpdateStatus[key].autoFilledFields = [];
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
prepare(payload = {}) {
|
|
710
|
+
return { payload };
|
|
711
|
+
},
|
|
712
|
+
},
|
|
595
713
|
},
|
|
596
714
|
});
|
|
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;
|
|
715
|
+
export const { fetchOnboardingCustomerView, fetchOnboardingCustomerSetupView, fetchOnboardingCustomerSetupViewSuccess, fetchOnboardingCustomerSetupViewFailure, updateOnboardingCustomerViewCompleteStatus, updateOnboardingCustomerViewCompleteStatusSuccess, updateOnboardingCustomerViewCompleteStatusFailure, acknowledgeOnboardingAiFinanceTeam, acknowledgeOnboardingAiFinanceTeamSuccess, acknowledgeOnboardingAiFinanceTeamFailure, fetchAiAgentsActivationStatus, fetchAiAgentsActivationStatusSuccess, fetchAiAgentsActivationStatusFailure, aiAgentsActivationCountsUpdated, aiAgentsActivationPhaseChanged, aiAgentsActivationSectionReady, 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, applyKycDocumentAutofillForOnboarding, applyKybDocumentAutofillForOnboarding, clearKycKybAutofillForOnboarding, } = onboardingCustomerView.actions;
|
|
598
716
|
export default onboardingCustomerView.reducer;
|
|
@@ -323,3 +323,17 @@ export const getProductSettingsString = (productSettings) => {
|
|
|
323
323
|
.map((key) => productKeyMap[key])
|
|
324
324
|
.join(',');
|
|
325
325
|
};
|
|
326
|
+
const fromActivationView = (state) => state.onboardingCustomerViewState.aiAgentsActivation;
|
|
327
|
+
export const getAiAgentsActivationSubview = (state) => fromActivationView(state);
|
|
328
|
+
export const getAiAgentsActivationLedgerPhases = (state) => fromActivationView(state).ledgerPhases;
|
|
329
|
+
export const getAiAgentsActivationBackgroundPhases = (state) => fromActivationView(state).backgroundPhases;
|
|
330
|
+
export const getAiAgentsActivationCounts = (state) => fromActivationView(state).counts;
|
|
331
|
+
const SECTION_ROW_STATUS_FALLBACK = 'idle';
|
|
332
|
+
const phaseStatusToRowStatus = (status) => {
|
|
333
|
+
if (status === 'ready') {
|
|
334
|
+
return 'building';
|
|
335
|
+
}
|
|
336
|
+
return status;
|
|
337
|
+
};
|
|
338
|
+
export const getAiAgentsActivationLedgerRowStatuses = (state) => fromActivationView(state).ledgerPhases.map((phase) => phaseStatusToRowStatus(phase.status ?? SECTION_ROW_STATUS_FALLBACK));
|
|
339
|
+
export const getAiAgentsActivationBackgroundRowStatuses = (state) => fromActivationView(state).backgroundPhases.map((phase) => phaseStatusToRowStatus(phase.status ?? SECTION_ROW_STATUS_FALLBACK));
|
|
@@ -26,3 +26,16 @@ export const ALL_ONBOARDING_STEPS = [
|
|
|
26
26
|
...ALL_ZENI_USER_ONBOARDING_STEPS_WITHOUT_ACCOUNT,
|
|
27
27
|
];
|
|
28
28
|
export const toOnboardingStepType = (v) => stringToUnion(v, ALL_ONBOARDING_STEPS);
|
|
29
|
+
export const emptyAiAgentsActivationCounts = {
|
|
30
|
+
customerCount: 0,
|
|
31
|
+
glAccountCount: 0,
|
|
32
|
+
targetTransactionCount: 0,
|
|
33
|
+
transactionCount: 0,
|
|
34
|
+
vendorCount: 0,
|
|
35
|
+
};
|
|
36
|
+
export const emptyAiAgentsActivationSubview = {
|
|
37
|
+
backgroundPhases: [],
|
|
38
|
+
counts: emptyAiAgentsActivationCounts,
|
|
39
|
+
fetchStatus: { fetchState: 'Not-Started', error: undefined },
|
|
40
|
+
ledgerPhases: [],
|
|
41
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
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 } 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
|
+
return zeniAPI
|
|
19
|
+
.postAndGetJSON(url, requestPayload)
|
|
20
|
+
.pipe(mergeMap((response) => {
|
|
21
|
+
if (!isSuccessResponse(response) || response.data == null) {
|
|
22
|
+
return of();
|
|
23
|
+
}
|
|
24
|
+
let result;
|
|
25
|
+
switch (documentType) {
|
|
26
|
+
case 'certificate_of_incorporation':
|
|
27
|
+
result = mapCoiToCompanyDetails(response.data);
|
|
28
|
+
break;
|
|
29
|
+
case 'tax_ein':
|
|
30
|
+
result = mapTaxEinToCompanyDetails(response.data);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
if (result.autoFilledFieldNames.length === 0) {
|
|
34
|
+
return of();
|
|
35
|
+
}
|
|
36
|
+
const applyAction = target === 'setup'
|
|
37
|
+
? applyKybDocumentAutofillForSetup({
|
|
38
|
+
companyId,
|
|
39
|
+
values: result.values,
|
|
40
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
41
|
+
})
|
|
42
|
+
: applyKybDocumentAutofillForOnboarding({
|
|
43
|
+
companyId,
|
|
44
|
+
values: result.values,
|
|
45
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
46
|
+
});
|
|
47
|
+
return of(applyAction);
|
|
48
|
+
}), catchError(() => of()));
|
|
49
|
+
}));
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { getCountryList } from '../../../../../entity/countryList/countryListSelector';
|
|
4
|
+
import { isSuccessResponse } from '../../../../../responsePayload';
|
|
5
|
+
import { applyKycDocumentAutofillForOnboarding } from '../../../../onboardingView/customerView/onboardingCustomerViewReducer';
|
|
6
|
+
import { parseUploadedKycDocument } 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
|
+
return zeniAPI
|
|
20
|
+
.postAndGetJSON(url, requestPayload)
|
|
21
|
+
.pipe(mergeMap((response) => {
|
|
22
|
+
if (!isSuccessResponse(response) || response.data == null) {
|
|
23
|
+
return of();
|
|
24
|
+
}
|
|
25
|
+
const allCountries = getCountryList(state$.value.countryListState, 'nationalityCountryList').countries;
|
|
26
|
+
let result;
|
|
27
|
+
switch (documentType) {
|
|
28
|
+
case 'passport':
|
|
29
|
+
result = mapPassportToOfficer(response.data, allCountries);
|
|
30
|
+
break;
|
|
31
|
+
case 'driving_license':
|
|
32
|
+
result = mapDrivingLicenseToOfficer(response.data);
|
|
33
|
+
break;
|
|
34
|
+
case 'social_security_card':
|
|
35
|
+
result = mapSsnCardToOfficer(response.data);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
if (result.autoFilledFieldNames.length === 0) {
|
|
39
|
+
return of();
|
|
40
|
+
}
|
|
41
|
+
const applyAction = target === 'setup'
|
|
42
|
+
? applyKycDocumentAutofillForSetup({
|
|
43
|
+
companyId,
|
|
44
|
+
officerType,
|
|
45
|
+
values: result.values,
|
|
46
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
47
|
+
})
|
|
48
|
+
: applyKycDocumentAutofillForOnboarding({
|
|
49
|
+
companyId,
|
|
50
|
+
officerType,
|
|
51
|
+
values: result.values,
|
|
52
|
+
autoFilledFieldNames: result.autoFilledFieldNames,
|
|
53
|
+
});
|
|
54
|
+
return of(applyAction);
|
|
55
|
+
}), catchError(() =>
|
|
56
|
+
// Autofill is best-effort; swallow errors silently so the user can keep typing.
|
|
57
|
+
of()));
|
|
58
|
+
}));
|
|
@@ -0,0 +1,12 @@
|
|
|
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');
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure mappers from ExtendAI parser payloads to our form-side local-data shapes.
|
|
3
|
+
*
|
|
4
|
+
* Each mapper filters out fields below KYC_KYB_AUTOFILL_MIN_CONFIDENCE and returns
|
|
5
|
+
* both the merged values and the list of field names that were autofilled so the
|
|
6
|
+
* UI can show the ✦ AI badge next to each.
|
|
7
|
+
*/
|
|
8
|
+
import { date } from '../../../zeniDayJS';
|
|
9
|
+
import { toZeniUrl } from '../../../zeniUrl';
|
|
10
|
+
import { KYC_KYB_AUTOFILL_MIN_CONFIDENCE, } from './types/kycKybAutofill';
|
|
11
|
+
const emptyResult = () => ({
|
|
12
|
+
values: {},
|
|
13
|
+
autoFilledFieldNames: [],
|
|
14
|
+
});
|
|
15
|
+
const isConfident = (field) => {
|
|
16
|
+
if (field == null) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (field.value == null) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return field.confidence >= KYC_KYB_AUTOFILL_MIN_CONFIDENCE;
|
|
23
|
+
};
|
|
24
|
+
const assignAutofilledValue = (result, key, value) => {
|
|
25
|
+
if (value == null) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === 'string' && value.trim() === '') {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
result.values[key] = value;
|
|
32
|
+
result.autoFilledFieldNames.push(key);
|
|
33
|
+
};
|
|
34
|
+
const tryParseDate = (rawDate) => {
|
|
35
|
+
const parsedDate = date(rawDate);
|
|
36
|
+
if (parsedDate.isValid()) {
|
|
37
|
+
return parsedDate;
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
};
|
|
41
|
+
const normalizeNationality = (rawNationality, countries) => {
|
|
42
|
+
const needle = rawNationality.trim().toLowerCase();
|
|
43
|
+
if (needle === '') {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
// Exact ISO-2 / ISO-3 match.
|
|
47
|
+
const isoMatch = countries.find((country) => country.countryCode.toLowerCase() === needle);
|
|
48
|
+
if (isoMatch != null) {
|
|
49
|
+
return isoMatch.countryCode;
|
|
50
|
+
}
|
|
51
|
+
// Common nationality adjectives map to country names (e.g. "American" → "United States").
|
|
52
|
+
const adjectiveToCountry = {
|
|
53
|
+
american: 'united states',
|
|
54
|
+
british: 'united kingdom',
|
|
55
|
+
indian: 'india',
|
|
56
|
+
canadian: 'canada',
|
|
57
|
+
australian: 'australia',
|
|
58
|
+
german: 'germany',
|
|
59
|
+
french: 'france',
|
|
60
|
+
chinese: 'china',
|
|
61
|
+
japanese: 'japan',
|
|
62
|
+
mexican: 'mexico',
|
|
63
|
+
brazilian: 'brazil',
|
|
64
|
+
};
|
|
65
|
+
const resolvedName = adjectiveToCountry[needle] ?? needle;
|
|
66
|
+
const nameMatch = countries.find((country) => country.countryName.toLowerCase() === resolvedName);
|
|
67
|
+
return nameMatch?.countryCode;
|
|
68
|
+
};
|
|
69
|
+
const splitFullName = (fullName) => {
|
|
70
|
+
const parts = fullName.trim().split(/\s+/);
|
|
71
|
+
if (parts.length === 1) {
|
|
72
|
+
return { firstName: parts[0], lastName: '' };
|
|
73
|
+
}
|
|
74
|
+
const lastName = parts[parts.length - 1];
|
|
75
|
+
const firstName = parts.slice(0, -1).join(' ');
|
|
76
|
+
return { firstName, lastName };
|
|
77
|
+
};
|
|
78
|
+
/** Passport → Company Officer. */
|
|
79
|
+
export const mapPassportToOfficer = (parsed, allNationalityCountries) => {
|
|
80
|
+
const result = emptyResult();
|
|
81
|
+
if (isConfident(parsed.first_name)) {
|
|
82
|
+
assignAutofilledValue(result, 'firstName', parsed.first_name.value);
|
|
83
|
+
}
|
|
84
|
+
if (isConfident(parsed.last_name)) {
|
|
85
|
+
assignAutofilledValue(result, 'lastName', parsed.last_name.value);
|
|
86
|
+
}
|
|
87
|
+
if (isConfident(parsed.date_of_birth)) {
|
|
88
|
+
const parsedDate = tryParseDate(parsed.date_of_birth.value);
|
|
89
|
+
if (parsedDate != null) {
|
|
90
|
+
assignAutofilledValue(result, 'birthday', parsedDate);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (isConfident(parsed.nationality)) {
|
|
94
|
+
const isoCode = normalizeNationality(parsed.nationality.value, allNationalityCountries);
|
|
95
|
+
if (isoCode != null) {
|
|
96
|
+
assignAutofilledValue(result, 'nationalityCountryCode', isoCode);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
};
|
|
101
|
+
/** Driving License → Company Officer. */
|
|
102
|
+
export const mapDrivingLicenseToOfficer = (parsed) => {
|
|
103
|
+
const result = emptyResult();
|
|
104
|
+
if (isConfident(parsed.first_name)) {
|
|
105
|
+
assignAutofilledValue(result, 'firstName', parsed.first_name.value);
|
|
106
|
+
}
|
|
107
|
+
if (isConfident(parsed.last_name)) {
|
|
108
|
+
assignAutofilledValue(result, 'lastName', parsed.last_name.value);
|
|
109
|
+
}
|
|
110
|
+
if (isConfident(parsed.date_of_birth)) {
|
|
111
|
+
const parsedDate = tryParseDate(parsed.date_of_birth.value);
|
|
112
|
+
if (parsedDate != null) {
|
|
113
|
+
assignAutofilledValue(result, 'birthday', parsedDate);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// address_* fields are mapped at a higher layer (addressView reducer) — kept here as values
|
|
117
|
+
// only, the consuming epic dispatches the address payload separately.
|
|
118
|
+
return result;
|
|
119
|
+
};
|
|
120
|
+
/** SSN Card → Company Officer (name only — SSN value not yet returned by parser). */
|
|
121
|
+
export const mapSsnCardToOfficer = (parsed) => {
|
|
122
|
+
const result = emptyResult();
|
|
123
|
+
if (isConfident(parsed.full_name)) {
|
|
124
|
+
const { firstName, lastName } = splitFullName(parsed.full_name.value);
|
|
125
|
+
if (firstName !== '') {
|
|
126
|
+
assignAutofilledValue(result, 'firstName', firstName);
|
|
127
|
+
}
|
|
128
|
+
if (lastName !== '') {
|
|
129
|
+
assignAutofilledValue(result, 'lastName', lastName);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
};
|
|
134
|
+
/** Certificate of Incorporation → Company Details. */
|
|
135
|
+
export const mapCoiToCompanyDetails = (parsed) => {
|
|
136
|
+
const result = emptyResult();
|
|
137
|
+
if (isConfident(parsed.company_legal_name)) {
|
|
138
|
+
assignAutofilledValue(result, 'companyLegalName', parsed.company_legal_name.value);
|
|
139
|
+
}
|
|
140
|
+
if (isConfident(parsed.ein)) {
|
|
141
|
+
assignAutofilledValue(result, 'taxIdOrEIN', parsed.ein.value);
|
|
142
|
+
}
|
|
143
|
+
if (isConfident(parsed.phone_number)) {
|
|
144
|
+
assignAutofilledValue(result, 'phone', parsed.phone_number.value);
|
|
145
|
+
}
|
|
146
|
+
if (isConfident(parsed.product_description)) {
|
|
147
|
+
assignAutofilledValue(result, 'companyDescription', parsed.product_description.value);
|
|
148
|
+
}
|
|
149
|
+
if (isConfident(parsed.website)) {
|
|
150
|
+
try {
|
|
151
|
+
assignAutofilledValue(result, 'website', toZeniUrl(parsed.website.value));
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// ignore — malformed URL string from OCR
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (isConfident(parsed.industry)) {
|
|
158
|
+
assignAutofilledValue(result, 'companyIndustryType', parsed.industry.value);
|
|
159
|
+
}
|
|
160
|
+
if (isConfident(parsed.sub_industry)) {
|
|
161
|
+
assignAutofilledValue(result, 'companySubIndustry', parsed.sub_industry.value);
|
|
162
|
+
}
|
|
163
|
+
if (isConfident(parsed.type_of_incorporation)) {
|
|
164
|
+
assignAutofilledValue(result, 'typeOfIncorporation', parsed.type_of_incorporation.value);
|
|
165
|
+
}
|
|
166
|
+
if (isConfident(parsed.date_of_incorporation)) {
|
|
167
|
+
const parsedDate = tryParseDate(parsed.date_of_incorporation.value);
|
|
168
|
+
if (parsedDate != null) {
|
|
169
|
+
assignAutofilledValue(result, 'incDate', parsedDate);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (isConfident(parsed.state_of_incorporation)) {
|
|
173
|
+
assignAutofilledValue(result, 'stateOfIncorporation', parsed.state_of_incorporation.value);
|
|
174
|
+
}
|
|
175
|
+
if (isConfident(parsed.countries_of_operations)) {
|
|
176
|
+
assignAutofilledValue(result, 'countriesOfOperations', parsed.countries_of_operations.value);
|
|
177
|
+
}
|
|
178
|
+
if (isConfident(parsed.source_of_funds)) {
|
|
179
|
+
assignAutofilledValue(result, 'sourceOfFunds', parsed.source_of_funds.value);
|
|
180
|
+
}
|
|
181
|
+
if (isConfident(parsed.transaction_volume_expectations)) {
|
|
182
|
+
assignAutofilledValue(result, 'transactionVolume', parsed.transaction_volume_expectations.value);
|
|
183
|
+
}
|
|
184
|
+
if (isConfident(parsed.purpose_of_account)) {
|
|
185
|
+
assignAutofilledValue(result, 'purposeOfAccount', parsed.purpose_of_account.value);
|
|
186
|
+
}
|
|
187
|
+
if (isConfident(parsed.regulated_status)) {
|
|
188
|
+
assignAutofilledValue(result, 'regulatedStatus', parsed.regulated_status.value);
|
|
189
|
+
}
|
|
190
|
+
if (isConfident(parsed.us_nexus)) {
|
|
191
|
+
assignAutofilledValue(result, 'usNexus', parsed.us_nexus.value);
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
};
|
|
195
|
+
/** Tax EIN letter → Company Details. */
|
|
196
|
+
export const mapTaxEinToCompanyDetails = (parsed) => {
|
|
197
|
+
const result = emptyResult();
|
|
198
|
+
if (isConfident(parsed.legal_business_name)) {
|
|
199
|
+
assignAutofilledValue(result, 'companyLegalName', parsed.legal_business_name.value);
|
|
200
|
+
}
|
|
201
|
+
if (isConfident(parsed.ein)) {
|
|
202
|
+
assignAutofilledValue(result, 'taxIdOrEIN', parsed.ein.value);
|
|
203
|
+
}
|
|
204
|
+
return result;
|
|
205
|
+
};
|