@zeniai/client-epic-state 5.1.4-beta7ND → 5.1.4-betaML2
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 +0 -4
- package/lib/entity/company/companyPayload.js +0 -6
- package/lib/entity/company/companyStateTypes.d.ts +0 -7
- package/lib/entity/paymentAccount/paymentAccountSelector.d.ts +0 -1
- package/lib/entity/paymentAccount/paymentAccountSelector.js +0 -9
- package/lib/entity/tenant/epic/deleteConnectionEpic.d.ts +1 -1
- 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 +0 -1
- package/lib/entity/tenant/tenantReducer.d.ts +25 -38
- package/lib/entity/tenant/tenantReducer.js +5 -65
- package/lib/entity/tenant/tenantState.d.ts +0 -1
- 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 +1 -6
- package/lib/epic.js +1 -7
- package/lib/esm/entity/company/companyPayload.js +0 -6
- package/lib/esm/entity/paymentAccount/paymentAccountSelector.js +0 -8
- package/lib/esm/entity/tenant/tenantReducer.js +3 -63
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +1 -0
- package/lib/esm/epic.js +1 -7
- package/lib/esm/index.js +7 -11
- 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/customerDetails/updateOnboardingCustomerViewEpic.js +18 -24
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.js +17 -29
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +51 -223
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewSelector.js +12 -24
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewState.js +6 -37
- package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +52 -106
- package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +1 -6
- package/lib/index.d.ts +10 -14
- package/lib/index.js +35 -64
- 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/customerDetails/updateOnboardingCustomerViewEpic.js +18 -24
- package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.d.ts +2 -2
- package/lib/view/onboardingView/customerView/epic/customerDetails/updateOnboardingCustomerViewLocalStoreDataEpic.js +15 -27
- package/lib/view/onboardingView/customerView/onboardingCustomerViewPayload.d.ts +0 -3
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +5 -44
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +52 -225
- package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.d.ts +1 -6
- package/lib/view/onboardingView/customerView/onboardingCustomerViewSelector.js +12 -27
- package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +8 -52
- package/lib/view/onboardingView/customerView/onboardingCustomerViewState.js +7 -39
- package/lib/view/spendManagement/commonSetup/setupViewReducer.d.ts +2 -28
- package/lib/view/spendManagement/commonSetup/setupViewReducer.js +53 -107
- package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +2 -7
- package/lib/view/spendManagement/commonSetup/setupViewSelector.js +1 -6
- package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +0 -19
- package/package.json +1 -1
- package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.d.ts +0 -21
- package/lib/entity/tenant/epic/initEmailConnectOAuthEpic.js +0 -59
- package/lib/esm/entity/tenant/epic/initEmailConnectOAuthEpic.js +0 -55
- package/lib/esm/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +0 -40
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.js +0 -29
- package/lib/esm/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +0 -40
- package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +0 -58
- package/lib/esm/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +0 -77
- package/lib/esm/view/spendManagement/commonSetup/kycKybAutofillActions.js +0 -14
- package/lib/esm/view/spendManagement/commonSetup/kycKybParseMapper.js +0 -207
- package/lib/esm/view/spendManagement/commonSetup/types/kycKybAutofill.js +0 -41
- package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.d.ts +0 -7
- package/lib/view/onboardingView/customerView/epic/aiAgentsActivation/fetchAiAgentsActivationStatusEpic.js +0 -44
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.d.ts +0 -8
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiActivationViewedEpic.js +0 -33
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.d.ts +0 -9
- package/lib/view/onboardingView/customerView/epic/customerDetails/acknowledgeOnboardingAiFinanceTeamEpic.js +0 -44
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.d.ts +0 -28
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKybDocumentEpic.js +0 -62
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.d.ts +0 -9
- package/lib/view/spendManagement/commonSetup/epic/setup/parseUploadedKycDocumentEpic.js +0 -81
- package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.d.ts +0 -24
- package/lib/view/spendManagement/commonSetup/kycKybAutofillActions.js +0 -17
- package/lib/view/spendManagement/commonSetup/kycKybParseMapper.d.ts +0 -29
- package/lib/view/spendManagement/commonSetup/kycKybParseMapper.js +0 -215
- package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.d.ts +0 -154
- package/lib/view/spendManagement/commonSetup/types/kycKybAutofill.js +0 -46
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.1.4-
|
|
3
|
+
"version": "5.1.4-betaML2",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
-
import { RootState } from '../../../reducer';
|
|
3
|
-
import { ZeniAPI } from '../../../zeniAPI';
|
|
4
|
-
import { initEmailConnectOAuth, initEmailConnectOAuthFailure, initEmailConnectOAuthSuccess } from '../tenantReducer';
|
|
5
|
-
export type ActionType = ReturnType<typeof initEmailConnectOAuth> | ReturnType<typeof initEmailConnectOAuthSuccess> | ReturnType<typeof initEmailConnectOAuthFailure>;
|
|
6
|
-
export type NavigateFn = (url: string) => void;
|
|
7
|
-
export declare const initEmailConnectOAuthEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI, navigate?: NavigateFn) => import("rxjs").Observable<{
|
|
8
|
-
payload: {
|
|
9
|
-
tenantId: string;
|
|
10
|
-
provider: "gmail" | "outlook";
|
|
11
|
-
authorizationUrl: string;
|
|
12
|
-
};
|
|
13
|
-
type: "tenant/initEmailConnectOAuthSuccess";
|
|
14
|
-
} | {
|
|
15
|
-
payload: {
|
|
16
|
-
tenantId: string;
|
|
17
|
-
provider: "gmail" | "outlook";
|
|
18
|
-
status: import("../../../responsePayload").ZeniAPIStatus<Record<string, unknown>>;
|
|
19
|
-
};
|
|
20
|
-
type: "tenant/initEmailConnectOAuthFailure";
|
|
21
|
-
}>;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initEmailConnectOAuthEpic = void 0;
|
|
4
|
-
const rxjs_1 = require("rxjs");
|
|
5
|
-
const operators_1 = require("rxjs/operators");
|
|
6
|
-
const responsePayload_1 = require("../../../responsePayload");
|
|
7
|
-
const tenantReducer_1 = require("../tenantReducer");
|
|
8
|
-
const defaultNavigate = (url) => {
|
|
9
|
-
// Production path: full-page redirect. The user's session continues on the
|
|
10
|
-
// provider's consent screen and lands back on this app via auth's HTML
|
|
11
|
-
// callback page (which itself redirects to redirect_after_url with the
|
|
12
|
-
// result encoded as a query param).
|
|
13
|
-
if (typeof window !== 'undefined') {
|
|
14
|
-
window.location.href = url;
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
// Backs the new POST /1.0/connectors/email/<provider>/init endpoint on the
|
|
18
|
-
// auth service. The endpoint creates a CSRF state token in the auth NDB
|
|
19
|
-
// store and returns the provider's authorization_url; this epic then drives
|
|
20
|
-
// a full-page redirect so the user lands on Google's / Microsoft's consent
|
|
21
|
-
// screen. After consent the user lands on auth's callback, which writes the
|
|
22
|
-
// resulting tokens through to tenant and redirects the browser back to
|
|
23
|
-
// ``redirectAfterUrl`` with ``?email_connect_result=<json>`` for the
|
|
24
|
-
// integrations page to consume on mount.
|
|
25
|
-
const initEmailConnectOAuthEpic = (actions$, _state$, zeniAPI,
|
|
26
|
-
// Test seam: callers can override to assert intended URL without actually
|
|
27
|
-
// navigating. Default is full-page redirect via window.location.
|
|
28
|
-
navigate = defaultNavigate) => actions$.pipe((0, operators_1.filter)(tenantReducer_1.initEmailConnectOAuth.match),
|
|
29
|
-
// Per-provider cancellation scope — switchMap at the outer level would
|
|
30
|
-
// cancel an in-flight gmail init when an outlook init fires, stranding
|
|
31
|
-
// the gmail provider's `saveConnectorCredentialsStateBySlug` in
|
|
32
|
-
// `In-Progress` forever. groupBy gives each provider its own stream.
|
|
33
|
-
(0, operators_1.groupBy)((action) => action.payload.provider), (0, operators_1.mergeMap)((perProvider$) => perProvider$.pipe((0, operators_1.switchMap)((action) => zeniAPI
|
|
34
|
-
.postAndGetJSON(`${zeniAPI.apiEndPoints.authMicroServiceBaseUrl}/1.0/connectors/email/${action.payload.provider}/init`, { redirect_after_url: action.payload.redirectAfterUrl }, { 'zeni-tenant-id': action.payload.tenantId })
|
|
35
|
-
.pipe((0, operators_1.mergeMap)((response) => {
|
|
36
|
-
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
37
|
-
// Fire-and-forget side effect — once the browser navigates,
|
|
38
|
-
// any further state we'd dispatch here is irrelevant. We still
|
|
39
|
-
// emit the success action so subscribers (tests, analytics)
|
|
40
|
-
// can observe the URL the epic decided to navigate to.
|
|
41
|
-
navigate(response.data.authorization_url);
|
|
42
|
-
return (0, rxjs_1.from)([
|
|
43
|
-
(0, tenantReducer_1.initEmailConnectOAuthSuccess)(action.payload.tenantId, action.payload.provider, response.data.authorization_url),
|
|
44
|
-
]);
|
|
45
|
-
}
|
|
46
|
-
const status = response.status ??
|
|
47
|
-
(0, responsePayload_1.createZeniAPIStatus)(`Failed to start ${action.payload.provider} connection. Please try again.`);
|
|
48
|
-
return (0, rxjs_1.from)([
|
|
49
|
-
(0, tenantReducer_1.initEmailConnectOAuthFailure)(action.payload.tenantId, action.payload.provider, status),
|
|
50
|
-
]);
|
|
51
|
-
}), (0, operators_1.catchError)((error) => {
|
|
52
|
-
const message = error instanceof Error
|
|
53
|
-
? error.message
|
|
54
|
-
: `Unexpected error starting ${action.payload.provider} connection.`;
|
|
55
|
-
return (0, rxjs_1.from)([
|
|
56
|
-
(0, tenantReducer_1.initEmailConnectOAuthFailure)(action.payload.tenantId, action.payload.provider, (0, responsePayload_1.createZeniAPIStatus)(message)),
|
|
57
|
-
]);
|
|
58
|
-
}))))));
|
|
59
|
-
exports.initEmailConnectOAuthEpic = initEmailConnectOAuthEpic;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { from } from 'rxjs';
|
|
2
|
-
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
4
|
-
import { initEmailConnectOAuth, initEmailConnectOAuthFailure, initEmailConnectOAuthSuccess, } from '../tenantReducer';
|
|
5
|
-
const defaultNavigate = (url) => {
|
|
6
|
-
// Production path: full-page redirect. The user's session continues on the
|
|
7
|
-
// provider's consent screen and lands back on this app via auth's HTML
|
|
8
|
-
// callback page (which itself redirects to redirect_after_url with the
|
|
9
|
-
// result encoded as a query param).
|
|
10
|
-
if (typeof window !== 'undefined') {
|
|
11
|
-
window.location.href = url;
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
// Backs the new POST /1.0/connectors/email/<provider>/init endpoint on the
|
|
15
|
-
// auth service. The endpoint creates a CSRF state token in the auth NDB
|
|
16
|
-
// store and returns the provider's authorization_url; this epic then drives
|
|
17
|
-
// a full-page redirect so the user lands on Google's / Microsoft's consent
|
|
18
|
-
// screen. After consent the user lands on auth's callback, which writes the
|
|
19
|
-
// resulting tokens through to tenant and redirects the browser back to
|
|
20
|
-
// ``redirectAfterUrl`` with ``?email_connect_result=<json>`` for the
|
|
21
|
-
// integrations page to consume on mount.
|
|
22
|
-
export const initEmailConnectOAuthEpic = (actions$, _state$, zeniAPI,
|
|
23
|
-
// Test seam: callers can override to assert intended URL without actually
|
|
24
|
-
// navigating. Default is full-page redirect via window.location.
|
|
25
|
-
navigate = defaultNavigate) => actions$.pipe(filter(initEmailConnectOAuth.match),
|
|
26
|
-
// Per-provider cancellation scope — switchMap at the outer level would
|
|
27
|
-
// cancel an in-flight gmail init when an outlook init fires, stranding
|
|
28
|
-
// the gmail provider's `saveConnectorCredentialsStateBySlug` in
|
|
29
|
-
// `In-Progress` forever. groupBy gives each provider its own stream.
|
|
30
|
-
groupBy((action) => action.payload.provider), mergeMap((perProvider$) => perProvider$.pipe(switchMap((action) => zeniAPI
|
|
31
|
-
.postAndGetJSON(`${zeniAPI.apiEndPoints.authMicroServiceBaseUrl}/1.0/connectors/email/${action.payload.provider}/init`, { redirect_after_url: action.payload.redirectAfterUrl }, { 'zeni-tenant-id': action.payload.tenantId })
|
|
32
|
-
.pipe(mergeMap((response) => {
|
|
33
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
34
|
-
// Fire-and-forget side effect — once the browser navigates,
|
|
35
|
-
// any further state we'd dispatch here is irrelevant. We still
|
|
36
|
-
// emit the success action so subscribers (tests, analytics)
|
|
37
|
-
// can observe the URL the epic decided to navigate to.
|
|
38
|
-
navigate(response.data.authorization_url);
|
|
39
|
-
return from([
|
|
40
|
-
initEmailConnectOAuthSuccess(action.payload.tenantId, action.payload.provider, response.data.authorization_url),
|
|
41
|
-
]);
|
|
42
|
-
}
|
|
43
|
-
const status = response.status ??
|
|
44
|
-
createZeniAPIStatus(`Failed to start ${action.payload.provider} connection. Please try again.`);
|
|
45
|
-
return from([
|
|
46
|
-
initEmailConnectOAuthFailure(action.payload.tenantId, action.payload.provider, status),
|
|
47
|
-
]);
|
|
48
|
-
}), catchError((error) => {
|
|
49
|
-
const message = error instanceof Error
|
|
50
|
-
? error.message
|
|
51
|
-
: `Unexpected error starting ${action.payload.provider} connection.`;
|
|
52
|
-
return from([
|
|
53
|
-
initEmailConnectOAuthFailure(action.payload.tenantId, action.payload.provider, createZeniAPIStatus(message)),
|
|
54
|
-
]);
|
|
55
|
-
}))))));
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
|
|
4
|
-
import { fetchAiAgentsActivationStatus, fetchAiAgentsActivationStatusFailure, fetchAiAgentsActivationStatusSuccess, } from '../../onboardingCustomerViewReducer';
|
|
5
|
-
const toPhaseStatus = (raw) => {
|
|
6
|
-
if (raw === 'idle' ||
|
|
7
|
-
raw === 'starting' ||
|
|
8
|
-
raw === 'building' ||
|
|
9
|
-
raw === 'ready') {
|
|
10
|
-
return raw;
|
|
11
|
-
}
|
|
12
|
-
return 'idle';
|
|
13
|
-
};
|
|
14
|
-
const toPhase = (row) => ({
|
|
15
|
-
key: row.key,
|
|
16
|
-
status: toPhaseStatus(row.status),
|
|
17
|
-
startedAt: row.started_at,
|
|
18
|
-
completedAt: row.completed_at,
|
|
19
|
-
});
|
|
20
|
-
const toCounts = (payload) => ({
|
|
21
|
-
customerCount: payload?.customer_count ?? 0,
|
|
22
|
-
glAccountCount: payload?.gl_account_count ?? 0,
|
|
23
|
-
targetTransactionCount: payload?.target_transaction_count ?? 0,
|
|
24
|
-
transactionCount: payload?.transaction_count ?? 0,
|
|
25
|
-
vendorCount: payload?.vendor_count ?? 0,
|
|
26
|
-
});
|
|
27
|
-
export const fetchAiAgentsActivationStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchAiAgentsActivationStatus.match), mergeMap(() => {
|
|
28
|
-
const url = `${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/ai-agents-activation/status`;
|
|
29
|
-
return zeniAPI.getJSON(url).pipe(mergeMap((response) => {
|
|
30
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
31
|
-
const phases = (response.data.phases ?? []).map(toPhase);
|
|
32
|
-
return of(fetchAiAgentsActivationStatusSuccess({
|
|
33
|
-
phases,
|
|
34
|
-
counts: toCounts(response.data.counts),
|
|
35
|
-
}));
|
|
36
|
-
}
|
|
37
|
-
return of(fetchAiAgentsActivationStatusFailure(response.status));
|
|
38
|
-
}), catchError((error) => of(fetchAiAgentsActivationStatusFailure(createZeniAPIStatus('Unexpected Error', 'fetchAiAgentsActivationStatus errored out ' +
|
|
39
|
-
JSON.stringify(error))))));
|
|
40
|
-
}));
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { updateCompanies } from '../../../../../entity/company/companyReducer';
|
|
4
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
|
|
5
|
-
import { acknowledgeOnboardingAiActivationViewed, acknowledgeOnboardingAiActivationViewedFailure, acknowledgeOnboardingAiActivationViewedSuccess, } from '../../onboardingCustomerViewReducer';
|
|
6
|
-
export const acknowledgeOnboardingAiActivationViewedEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(acknowledgeOnboardingAiActivationViewed.match), mergeMap((action) => {
|
|
7
|
-
const { companyId } = action.payload;
|
|
8
|
-
const payload = {
|
|
9
|
-
is_onboarding_ai_activation_viewed: true,
|
|
10
|
-
};
|
|
11
|
-
return zeniAPI
|
|
12
|
-
.putAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/companies/${companyId}`, payload)
|
|
13
|
-
.pipe(mergeMap((response) => {
|
|
14
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
15
|
-
const actions = [
|
|
16
|
-
updateCompanies({
|
|
17
|
-
payload: response.data.companies,
|
|
18
|
-
schema: {},
|
|
19
|
-
}),
|
|
20
|
-
acknowledgeOnboardingAiActivationViewedSuccess(),
|
|
21
|
-
];
|
|
22
|
-
return from(actions);
|
|
23
|
-
}
|
|
24
|
-
return of(acknowledgeOnboardingAiActivationViewedFailure(response.status));
|
|
25
|
-
}),
|
|
26
|
-
// Best-effort — failure is silent; cascade just runs again next visit.
|
|
27
|
-
catchError((error) => of(acknowledgeOnboardingAiActivationViewedFailure(createZeniAPIStatus('Unexpected Error', 'Acknowledge - Onboarding AI Activation Viewed errored out' +
|
|
28
|
-
JSON.stringify(error))))));
|
|
29
|
-
}));
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { updateCompanies } from '../../../../../entity/company/companyReducer';
|
|
4
|
-
import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
|
|
5
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
|
|
6
|
-
import { acknowledgeOnboardingAiFinanceTeam, acknowledgeOnboardingAiFinanceTeamFailure, acknowledgeOnboardingAiFinanceTeamSuccess, } from '../../onboardingCustomerViewReducer';
|
|
7
|
-
export const acknowledgeOnboardingAiFinanceTeamEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(acknowledgeOnboardingAiFinanceTeam.match), mergeMap((action) => {
|
|
8
|
-
const { companyId } = action.payload;
|
|
9
|
-
const payload = {
|
|
10
|
-
is_onboarding_ai_finance_team_acknowledged: true,
|
|
11
|
-
};
|
|
12
|
-
return zeniAPI
|
|
13
|
-
.putAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/companies/${companyId}`, payload)
|
|
14
|
-
.pipe(mergeMap((response) => {
|
|
15
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
16
|
-
const actions = [
|
|
17
|
-
updateCompanies({
|
|
18
|
-
payload: response.data.companies,
|
|
19
|
-
schema: {},
|
|
20
|
-
}),
|
|
21
|
-
acknowledgeOnboardingAiFinanceTeamSuccess(),
|
|
22
|
-
];
|
|
23
|
-
return from(actions);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
return of(openSnackbar({
|
|
27
|
-
messageSection: 'onboarding_customer_view_complete',
|
|
28
|
-
messageText: 'failed',
|
|
29
|
-
type: 'error',
|
|
30
|
-
variables: [
|
|
31
|
-
{
|
|
32
|
-
variableName: '_api-error_',
|
|
33
|
-
variableValue: response.status.message,
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
}), acknowledgeOnboardingAiFinanceTeamFailure(response.status));
|
|
37
|
-
}
|
|
38
|
-
}), catchError((error) => of(acknowledgeOnboardingAiFinanceTeamFailure(createZeniAPIStatus('Unexpected Error', 'Acknowledge - Onboarding AI Finance Team errored out' +
|
|
39
|
-
JSON.stringify(error))))));
|
|
40
|
-
}));
|
|
@@ -1,58 +0,0 @@
|
|
|
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
|
-
}));
|
|
@@ -1,77 +0,0 @@
|
|
|
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
|
-
}));
|
|
@@ -1,14 +0,0 @@
|
|
|
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');
|
|
@@ -1,207 +0,0 @@
|
|
|
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
|
-
export const OFFICER_ADDRESS_AUTOFILL_FIELD = 'officerAddress';
|
|
12
|
-
// US driving licenses carry a US state in `address_state` but no country field;
|
|
13
|
-
// default the composed address to the US.
|
|
14
|
-
const DRIVING_LICENSE_DEFAULT_COUNTRY = 'United States';
|
|
15
|
-
const DRIVING_LICENSE_DEFAULT_COUNTRY_CODE = 'US';
|
|
16
|
-
const emptyResult = () => ({
|
|
17
|
-
values: {},
|
|
18
|
-
autoFilledFieldNames: [],
|
|
19
|
-
});
|
|
20
|
-
const isConfident = (field) => {
|
|
21
|
-
if (field == null) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
if (field.value == null) {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
return field.confidence >= KYC_KYB_AUTOFILL_MIN_CONFIDENCE;
|
|
28
|
-
};
|
|
29
|
-
const assignAutofilledValue = (result, key, value) => {
|
|
30
|
-
if (value == null) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (typeof value === 'string' && value.trim() === '') {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
result.values[key] = value;
|
|
37
|
-
result.autoFilledFieldNames.push(key);
|
|
38
|
-
};
|
|
39
|
-
const tryParseDate = (rawDate) => {
|
|
40
|
-
const parsedDate = date(rawDate);
|
|
41
|
-
if (parsedDate.isValid()) {
|
|
42
|
-
return parsedDate;
|
|
43
|
-
}
|
|
44
|
-
return undefined;
|
|
45
|
-
};
|
|
46
|
-
const splitFullName = (fullName) => {
|
|
47
|
-
const parts = fullName.trim().split(/\s+/);
|
|
48
|
-
if (parts.length === 1) {
|
|
49
|
-
return { firstName: parts[0], lastName: '' };
|
|
50
|
-
}
|
|
51
|
-
const lastName = parts[parts.length - 1];
|
|
52
|
-
const firstName = parts.slice(0, -1).join(' ');
|
|
53
|
-
return { firstName, lastName };
|
|
54
|
-
};
|
|
55
|
-
/** Passport → Company Officer. */
|
|
56
|
-
export const mapPassportToOfficer = (parsed) => {
|
|
57
|
-
const result = emptyResult();
|
|
58
|
-
if (isConfident(parsed.first_name)) {
|
|
59
|
-
assignAutofilledValue(result, 'firstName', parsed.first_name.value);
|
|
60
|
-
}
|
|
61
|
-
if (isConfident(parsed.last_name)) {
|
|
62
|
-
assignAutofilledValue(result, 'lastName', parsed.last_name.value);
|
|
63
|
-
}
|
|
64
|
-
if (isConfident(parsed.date_of_birth)) {
|
|
65
|
-
const parsedDate = tryParseDate(parsed.date_of_birth.value);
|
|
66
|
-
if (parsedDate != null) {
|
|
67
|
-
assignAutofilledValue(result, 'birthday', parsedDate);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// The raw nationality string (e.g. "USA", "UNITED STATES OF AMERICA") is
|
|
71
|
-
// passed through unresolved; the consuming form section normalizes it to an
|
|
72
|
-
// ISO-2 code via the `countries-list` dataset before `setValue`. The form
|
|
73
|
-
// value (not this localData seed) is what gets submitted.
|
|
74
|
-
if (isConfident(parsed.nationality)) {
|
|
75
|
-
assignAutofilledValue(result, 'nationalityCountryCode', parsed.nationality.value);
|
|
76
|
-
}
|
|
77
|
-
return result;
|
|
78
|
-
};
|
|
79
|
-
/** Driving License → Company Officer (name, DOB, and home address). */
|
|
80
|
-
export const mapDrivingLicenseToOfficer = (parsed) => {
|
|
81
|
-
const result = emptyResult();
|
|
82
|
-
if (isConfident(parsed.first_name)) {
|
|
83
|
-
assignAutofilledValue(result, 'firstName', parsed.first_name.value);
|
|
84
|
-
}
|
|
85
|
-
if (isConfident(parsed.last_name)) {
|
|
86
|
-
assignAutofilledValue(result, 'lastName', parsed.last_name.value);
|
|
87
|
-
}
|
|
88
|
-
if (isConfident(parsed.date_of_birth)) {
|
|
89
|
-
const parsedDate = tryParseDate(parsed.date_of_birth.value);
|
|
90
|
-
if (parsedDate != null) {
|
|
91
|
-
assignAutofilledValue(result, 'birthday', parsedDate);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
// The officer address lives in the addressView slice rather than
|
|
95
|
-
// CompanyOfficerLocalData, so it's returned separately for the epic to
|
|
96
|
-
// dispatch via newAddressInLocalStore.
|
|
97
|
-
const street = isConfident(parsed.address_street)
|
|
98
|
-
? parsed.address_street.value.trim()
|
|
99
|
-
: undefined;
|
|
100
|
-
const city = isConfident(parsed.address_city)
|
|
101
|
-
? parsed.address_city.value.trim()
|
|
102
|
-
: undefined;
|
|
103
|
-
const state = isConfident(parsed.address_state)
|
|
104
|
-
? parsed.address_state.value.trim()
|
|
105
|
-
: undefined;
|
|
106
|
-
const postalCode = isConfident(parsed.address_zip)
|
|
107
|
-
? parsed.address_zip.value.trim()
|
|
108
|
-
: undefined;
|
|
109
|
-
if (street != null || city != null || state != null || postalCode != null) {
|
|
110
|
-
result.address = {
|
|
111
|
-
street: street != null ? [street] : [],
|
|
112
|
-
city: city ?? '',
|
|
113
|
-
state: state ?? '',
|
|
114
|
-
postalCode: postalCode ?? '',
|
|
115
|
-
country: DRIVING_LICENSE_DEFAULT_COUNTRY,
|
|
116
|
-
countryCode: DRIVING_LICENSE_DEFAULT_COUNTRY_CODE,
|
|
117
|
-
};
|
|
118
|
-
result.autoFilledFieldNames.push(OFFICER_ADDRESS_AUTOFILL_FIELD);
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
};
|
|
122
|
-
/** SSN Card → Company Officer (name only — SSN value not yet returned by parser). */
|
|
123
|
-
export const mapSsnCardToOfficer = (parsed) => {
|
|
124
|
-
const result = emptyResult();
|
|
125
|
-
if (isConfident(parsed.full_name)) {
|
|
126
|
-
const { firstName, lastName } = splitFullName(parsed.full_name.value);
|
|
127
|
-
if (firstName !== '') {
|
|
128
|
-
assignAutofilledValue(result, 'firstName', firstName);
|
|
129
|
-
}
|
|
130
|
-
if (lastName !== '') {
|
|
131
|
-
assignAutofilledValue(result, 'lastName', lastName);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return result;
|
|
135
|
-
};
|
|
136
|
-
/** Certificate of Incorporation → Company Details. */
|
|
137
|
-
export const mapCoiToCompanyDetails = (parsed) => {
|
|
138
|
-
const result = emptyResult();
|
|
139
|
-
if (isConfident(parsed.company_legal_name)) {
|
|
140
|
-
assignAutofilledValue(result, 'companyLegalName', parsed.company_legal_name.value);
|
|
141
|
-
}
|
|
142
|
-
if (isConfident(parsed.ein)) {
|
|
143
|
-
assignAutofilledValue(result, 'taxIdOrEIN', parsed.ein.value);
|
|
144
|
-
}
|
|
145
|
-
if (isConfident(parsed.phone_number)) {
|
|
146
|
-
assignAutofilledValue(result, 'phone', parsed.phone_number.value);
|
|
147
|
-
}
|
|
148
|
-
if (isConfident(parsed.product_description)) {
|
|
149
|
-
assignAutofilledValue(result, 'companyDescription', parsed.product_description.value);
|
|
150
|
-
}
|
|
151
|
-
if (isConfident(parsed.website)) {
|
|
152
|
-
try {
|
|
153
|
-
assignAutofilledValue(result, 'website', toZeniUrl(parsed.website.value));
|
|
154
|
-
}
|
|
155
|
-
catch {
|
|
156
|
-
// ignore — malformed URL string from OCR
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
if (isConfident(parsed.industry)) {
|
|
160
|
-
assignAutofilledValue(result, 'companyIndustryType', parsed.industry.value);
|
|
161
|
-
}
|
|
162
|
-
if (isConfident(parsed.sub_industry)) {
|
|
163
|
-
assignAutofilledValue(result, 'companySubIndustry', parsed.sub_industry.value);
|
|
164
|
-
}
|
|
165
|
-
if (isConfident(parsed.type_of_incorporation)) {
|
|
166
|
-
assignAutofilledValue(result, 'typeOfIncorporation', parsed.type_of_incorporation.value);
|
|
167
|
-
}
|
|
168
|
-
if (isConfident(parsed.date_of_incorporation)) {
|
|
169
|
-
const parsedDate = tryParseDate(parsed.date_of_incorporation.value);
|
|
170
|
-
if (parsedDate != null) {
|
|
171
|
-
assignAutofilledValue(result, 'incDate', parsedDate);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (isConfident(parsed.state_of_incorporation)) {
|
|
175
|
-
assignAutofilledValue(result, 'stateOfIncorporation', parsed.state_of_incorporation.value);
|
|
176
|
-
}
|
|
177
|
-
if (isConfident(parsed.countries_of_operations)) {
|
|
178
|
-
assignAutofilledValue(result, 'countriesOfOperations', parsed.countries_of_operations.value);
|
|
179
|
-
}
|
|
180
|
-
if (isConfident(parsed.source_of_funds)) {
|
|
181
|
-
assignAutofilledValue(result, 'sourceOfFunds', parsed.source_of_funds.value);
|
|
182
|
-
}
|
|
183
|
-
if (isConfident(parsed.transaction_volume_expectations)) {
|
|
184
|
-
assignAutofilledValue(result, 'transactionVolume', parsed.transaction_volume_expectations.value);
|
|
185
|
-
}
|
|
186
|
-
if (isConfident(parsed.purpose_of_account)) {
|
|
187
|
-
assignAutofilledValue(result, 'purposeOfAccount', parsed.purpose_of_account.value);
|
|
188
|
-
}
|
|
189
|
-
if (isConfident(parsed.regulated_status)) {
|
|
190
|
-
assignAutofilledValue(result, 'regulatedStatus', parsed.regulated_status.value);
|
|
191
|
-
}
|
|
192
|
-
if (isConfident(parsed.us_nexus)) {
|
|
193
|
-
assignAutofilledValue(result, 'usNexus', parsed.us_nexus.value);
|
|
194
|
-
}
|
|
195
|
-
return result;
|
|
196
|
-
};
|
|
197
|
-
/** Tax EIN letter → Company Details. */
|
|
198
|
-
export const mapTaxEinToCompanyDetails = (parsed) => {
|
|
199
|
-
const result = emptyResult();
|
|
200
|
-
if (isConfident(parsed.legal_business_name)) {
|
|
201
|
-
assignAutofilledValue(result, 'companyLegalName', parsed.legal_business_name.value);
|
|
202
|
-
}
|
|
203
|
-
if (isConfident(parsed.ein)) {
|
|
204
|
-
assignAutofilledValue(result, 'taxIdOrEIN', parsed.ein.value);
|
|
205
|
-
}
|
|
206
|
-
return result;
|
|
207
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/** Confidence floor below which we drop an autofill candidate. */
|
|
2
|
-
export const KYC_KYB_AUTOFILL_MIN_CONFIDENCE = 0.5;
|
|
3
|
-
/**
|
|
4
|
-
* Maps the form-side {@link KycSelectDocumentType} (camelCase) to the
|
|
5
|
-
* parser-side {@link KycProvidedDocumentType} (snake_case). Returns `null` for
|
|
6
|
-
* `stateId`, which has no parser today.
|
|
7
|
-
*/
|
|
8
|
-
export const toKycProvidedDocumentType = (selectType) => {
|
|
9
|
-
switch (selectType) {
|
|
10
|
-
case 'driverLicense':
|
|
11
|
-
return 'driving_license';
|
|
12
|
-
case 'passport':
|
|
13
|
-
return 'passport';
|
|
14
|
-
case 'ssnCard':
|
|
15
|
-
return 'social_security_card';
|
|
16
|
-
case 'stateId':
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Maps a persisted {@link AllowedDocumentType} (snake_case — the value stored on
|
|
22
|
-
* an officer's `documentTypeSelectedForVerification`) to the parser-side
|
|
23
|
-
* {@link KycProvidedDocumentType}. Returns `null` for document types with no KYC
|
|
24
|
-
* parser today (e.g. `id_document` / state ID, and any non-identity doc).
|
|
25
|
-
*
|
|
26
|
-
* The officer's stored selection is an `AllowedDocumentType`, not a
|
|
27
|
-
* {@link KycSelectDocumentType}; use this — not {@link toKycProvidedDocumentType}
|
|
28
|
-
* — when triggering autofill off that field.
|
|
29
|
-
*/
|
|
30
|
-
export const toKycProvidedDocumentTypeFromAllowed = (allowedType) => {
|
|
31
|
-
switch (allowedType) {
|
|
32
|
-
case 'passport':
|
|
33
|
-
return 'passport';
|
|
34
|
-
case 'driving_license':
|
|
35
|
-
return 'driving_license';
|
|
36
|
-
case 'social_security_card':
|
|
37
|
-
return 'social_security_card';
|
|
38
|
-
default:
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
};
|