@zeniai/client-epic-state 5.0.80 → 5.0.81-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/cacheOverrideFetchReducer.d.ts +17 -0
- package/lib/commonStateTypes/cacheOverrideFetchReducer.js +20 -0
- package/lib/commonStateTypes/filterPrimitives.d.ts +23 -0
- package/lib/commonStateTypes/filterPrimitives.js +21 -0
- package/lib/commonStateTypes/pusherActions.d.ts +11 -0
- package/lib/commonStateTypes/pusherActions.js +6 -0
- package/lib/coreEpics.js +1 -1
- package/lib/entity/account/accountSelector.d.ts +27 -1
- package/lib/entity/account/accountSelector.js +47 -1
- package/lib/entity/account/accountState.d.ts +6 -1
- package/lib/entity/account/accountState.js +11 -4
- package/lib/entity/account/subAccountSelector.d.ts +1 -1
- package/lib/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +1 -3
- package/lib/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +1 -2
- package/lib/entity/aiAccountantCustomer/aiAccountantCustomerSelector.d.ts +1 -1
- package/lib/entity/chargeCard/chargeCardReducer.d.ts +19 -2
- package/lib/entity/chargeCard/chargeCardReducer.js +35 -2
- package/lib/entity/chargeCardTransaction/chargeCardTransactionReducer.d.ts +14 -1
- package/lib/entity/chargeCardTransaction/chargeCardTransactionReducer.js +36 -2
- package/lib/entity/class/classSelector.d.ts +35 -0
- package/lib/entity/class/classSelector.js +50 -0
- package/lib/entity/paymentAccount/paymentAccountSelector.d.ts +1 -0
- package/lib/entity/paymentAccount/paymentAccountSelector.js +4 -0
- package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +1 -1
- package/lib/entity/sectionProjectView/sectionProjectViewSelector.js +1 -1
- package/lib/entity/tenant/SessionManager.js +6 -3
- package/lib/entity/tenant/clearAllEpic.d.ts +2 -2
- package/lib/entity/tenant/clearAllEpic.js +2 -2
- 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/saveAPIKeyConnectionEpic.js +6 -2
- package/lib/entity/tenant/epic/saveConnectorCredentialsEpic.d.ts +3 -3
- package/lib/entity/tenant/epic/saveOAuthConnectionEpic.d.ts +1 -1
- package/lib/entity/tenant/epic/saveOAuthConnectionEpic.js +6 -2
- package/lib/entity/tenant/tenantPayload.d.ts +1 -0
- package/lib/entity/tenant/tenantReducer.d.ts +38 -25
- package/lib/entity/tenant/tenantReducer.js +71 -6
- package/lib/entity/tenant/tenantState.d.ts +1 -0
- package/lib/entity/transaction/payloadTypes/transactionLinePayload.js +3 -1
- package/lib/epic.d.ts +13 -11
- package/lib/epic.js +15 -12
- package/lib/esm/commonStateTypes/cacheOverrideFetchReducer.js +16 -0
- package/lib/esm/commonStateTypes/filterPrimitives.js +20 -0
- package/lib/esm/commonStateTypes/pusherActions.js +3 -0
- package/lib/esm/coreEpics.js +1 -1
- package/lib/esm/entity/account/accountSelector.js +46 -1
- package/lib/esm/entity/account/accountState.js +7 -1
- package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +1 -3
- package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +1 -2
- package/lib/esm/entity/chargeCard/chargeCardReducer.js +34 -1
- package/lib/esm/entity/chargeCardTransaction/chargeCardTransactionReducer.js +35 -1
- package/lib/esm/entity/class/classSelector.js +48 -0
- package/lib/esm/entity/paymentAccount/paymentAccountSelector.js +3 -0
- package/lib/esm/entity/sectionProjectView/sectionProjectViewSelector.js +1 -1
- package/lib/esm/entity/tenant/SessionManager.js +4 -1
- package/lib/esm/entity/tenant/clearAllEpic.js +2 -2
- package/lib/esm/entity/tenant/epic/initEmailConnectOAuthEpic.js +50 -0
- package/lib/esm/entity/tenant/epic/saveAPIKeyConnectionEpic.js +6 -2
- package/lib/esm/entity/tenant/epic/saveOAuthConnectionEpic.js +6 -2
- package/lib/esm/entity/tenant/tenantReducer.js +69 -4
- package/lib/esm/entity/transaction/payloadTypes/transactionLinePayload.js +3 -1
- package/lib/esm/epic.js +15 -12
- package/lib/esm/index.js +38 -25
- package/lib/esm/reducer.js +2 -2
- package/lib/esm/view/aiAccountantView/epics/fetchAiAccountantCustomersEpic.js +2 -5
- package/lib/esm/view/aiAccountantView/epics/fetchAiAccountantJobsEpic.js +2 -5
- package/lib/esm/view/aiAccountantView/epics/triggerAiAccountantJobEpic.js +4 -1
- package/lib/esm/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
- package/lib/esm/view/companyTaskManagerView/companyTaskManagerViewSelector.js +1 -1
- package/lib/esm/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +1 -1
- package/lib/esm/view/companyView/helpers/cockpitHelpers.js +1 -1
- package/lib/esm/view/companyView/selector/companyManagementViewSelector.js +1 -1
- package/lib/esm/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
- package/lib/esm/view/creditAgentView/creditAgentViewReducer.js +1 -16
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +2 -2
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +2 -1
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/restoreBulkUploadAutomatchingOnMountEpic.js +8 -6
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +7 -1
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +11 -1
- package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +21 -1
- package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +2 -1
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +253 -14
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +147 -13
- package/lib/esm/view/expenseAutomationView/transactionFilterHelpers.js +258 -0
- package/lib/esm/view/expenseAutomationView/types/completedSubTab.js +17 -0
- package/lib/esm/view/expenseAutomationView/types/missingReceiptsViewState.js +0 -2
- package/lib/esm/view/financeStatement/financeStatementSelector.js +1 -1
- package/lib/esm/view/onboardingView/customerView/onboardingCustomerViewReducer.js +61 -50
- package/lib/esm/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +87 -0
- package/lib/esm/view/recommendation/recommendationHelper.js +29 -0
- package/lib/esm/view/recommendation/recommendationReducer.js +26 -1
- package/lib/esm/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.js +3 -2
- package/lib/esm/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.js +3 -2
- package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/chargeCardDetailReducer.js +55 -18
- package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailEpic.js +16 -2
- package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailPageEpic.js +5 -4
- package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.js +26 -9
- package/lib/esm/view/spendManagement/chargeCards/chargeCardList/fetchChargeCardListPageEpic.js +9 -6
- package/lib/esm/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.js +3 -2
- package/lib/esm/view/spendManagement/chargeCards/chargeCardPaymentHistory/fetchChargeCardPaymentPageEpic.js +1 -1
- package/lib/esm/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.js +7 -3
- 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/esm/view/spendManagement/spendManagementFilterHelpers.js +4 -2
- package/lib/esm/view/subscriptionView/subscriptionViewSelector.js +1 -1
- package/lib/esm/view/taskManager/cannedResponsesView/epics/fetchCannedResponsesEpic.js +1 -1
- package/lib/esm/view/taskManager/cannedResponsesView/epics/saveCannedResponseEpic.js +1 -1
- package/lib/esm/view/taskManager/taskDetailView/epics/unsnoozeTaskEpic.js +1 -1
- package/lib/esm/view/taskManager/taskListView/taskListReducer.js +1 -1
- package/lib/esm/view/transactionDetail/transactionDetailReducer.js +121 -6
- package/lib/esm/view/transactionDetail/transactionDetailSelector.js +29 -1
- package/lib/index.d.ts +39 -28
- package/lib/index.js +97 -60
- package/lib/reducer.d.ts +2 -2
- package/lib/reducer.js +2 -2
- package/lib/view/aiAccountantView/aiAccountantViewPayload.d.ts +2 -2
- package/lib/view/aiAccountantView/aiAccountantViewReducer.d.ts +1 -1
- package/lib/view/aiAccountantView/epics/fetchAiAccountantCustomersEpic.js +2 -5
- package/lib/view/aiAccountantView/epics/fetchAiAccountantJobsEpic.js +2 -5
- package/lib/view/aiAccountantView/epics/triggerAiAccountantJobEpic.js +4 -1
- package/lib/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
- package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.d.ts +1 -1
- package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.js +1 -1
- package/lib/view/companyView/helpers/cockpitHelpers.js +1 -1
- package/lib/view/companyView/selector/companyManagementViewSelector.js +1 -1
- package/lib/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
- package/lib/view/companyView/types/cockpitTypes.d.ts +1 -1
- package/lib/view/creditAgentView/creditAgentViewPayload.d.ts +0 -3
- package/lib/view/creditAgentView/creditAgentViewReducer.d.ts +1 -1
- package/lib/view/creditAgentView/creditAgentViewReducer.js +2 -17
- package/lib/view/creditAgentView/creditAgentViewState.d.ts +0 -5
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +2 -2
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +2 -1
- package/lib/view/expenseAutomationView/epics/missingReceipts/restoreBulkUploadAutomatchingOnMountEpic.js +8 -6
- package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +7 -1
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.d.ts +2 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +10 -0
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +2 -1
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +23 -2
- package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +21 -0
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +2 -1
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +2 -1
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +28 -5
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +253 -14
- package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +2 -1
- package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +16 -0
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +7 -1
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +150 -13
- package/lib/view/expenseAutomationView/transactionFilterHelpers.d.ts +66 -0
- package/lib/view/expenseAutomationView/transactionFilterHelpers.js +262 -0
- package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +10 -0
- package/lib/view/expenseAutomationView/types/completedSubTab.js +21 -0
- package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +1 -2
- package/lib/view/expenseAutomationView/types/missingReceiptsViewState.js +1 -4
- package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +44 -2
- package/lib/view/financeStatement/financeStatementSelector.js +1 -1
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.d.ts +25 -2
- package/lib/view/onboardingView/customerView/onboardingCustomerViewReducer.js +62 -51
- package/lib/view/onboardingView/customerView/onboardingCustomerViewState.d.ts +10 -0
- package/lib/view/profitAndLossProjectView/profitAndLossProjectViewSelectorTypes.d.ts +1 -1
- package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.d.ts +9 -0
- package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +91 -0
- package/lib/view/recommendation/recommendationHelper.d.ts +9 -0
- package/lib/view/recommendation/recommendationHelper.js +31 -1
- package/lib/view/recommendation/recommendationReducer.d.ts +20 -1
- package/lib/view/recommendation/recommendationReducer.js +27 -2
- package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
- package/lib/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.d.ts +3 -1
- package/lib/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.js +3 -2
- package/lib/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.d.ts +3 -1
- package/lib/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.js +3 -2
- package/lib/view/spendManagement/chargeCards/chargeCardDetail/chargeCardDetailReducer.js +55 -18
- package/lib/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailEpic.js +16 -2
- package/lib/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailPageEpic.js +5 -4
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.d.ts +18 -3
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.js +27 -10
- package/lib/view/spendManagement/chargeCards/chargeCardList/fetchChargeCardListPageEpic.js +9 -6
- package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistory.d.ts +1 -1
- package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.d.ts +3 -1
- package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.js +3 -2
- package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/fetchChargeCardPaymentPageEpic.js +1 -1
- package/lib/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.d.ts +3 -1
- package/lib/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.js +7 -3
- 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/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
- package/lib/view/spendManagement/spendManagementFilterHelpers.d.ts +12 -3
- package/lib/view/spendManagement/spendManagementFilterHelpers.js +4 -2
- package/lib/view/subscriptionView/subscriptionViewSelector.js +1 -1
- package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
- package/lib/view/taskManager/taskListView/taskListReducer.js +1 -1
- package/lib/view/transactionDetail/transactionDetailReducer.d.ts +11 -1
- package/lib/view/transactionDetail/transactionDetailReducer.js +122 -7
- package/lib/view/transactionDetail/transactionDetailSelector.d.ts +2 -0
- package/lib/view/transactionDetail/transactionDetailSelector.js +31 -2
- package/lib/view/transactionDetail/transactionDetailTypes.d.ts +1 -0
- package/lib/view/zeniOAuthView/zeniOAuthSelector.d.ts +1 -1
- package/package.json +10 -4
- package/lib/esm/view/creditAgentView/epics/fetchCreditAgentAccessEpic.js +0 -13
- package/lib/tsconfig.typecheck.tsbuildinfo +0 -1
- package/lib/view/creditAgentView/epics/fetchCreditAgentAccessEpic.d.ts +0 -11
- package/lib/view/creditAgentView/epics/fetchCreditAgentAccessEpic.js +0 -17
|
@@ -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
|
+
};
|
|
@@ -3,60 +3,26 @@ const initialFetchStatus = {
|
|
|
3
3
|
fetchState: 'Not-Started',
|
|
4
4
|
error: undefined,
|
|
5
5
|
};
|
|
6
|
+
const emptyOfficerSlot = {
|
|
7
|
+
autoFilledFields: [],
|
|
8
|
+
localData: undefined,
|
|
9
|
+
sendOtpStatus: initialFetchStatus,
|
|
10
|
+
otpverificationStatus: initialFetchStatus,
|
|
11
|
+
};
|
|
6
12
|
export const initialState = {
|
|
7
13
|
updateStatus: { fetchState: 'Not-Started', error: undefined },
|
|
8
|
-
companyDetails: {},
|
|
14
|
+
companyDetails: { autoFilledFields: [] },
|
|
9
15
|
companyOfficerUpdateStatus: {
|
|
10
|
-
Officer_1: {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
},
|
|
20
|
-
Officer_3: {
|
|
21
|
-
localData: undefined,
|
|
22
|
-
sendOtpStatus: initialFetchStatus,
|
|
23
|
-
otpverificationStatus: initialFetchStatus,
|
|
24
|
-
},
|
|
25
|
-
Officer_4: {
|
|
26
|
-
localData: undefined,
|
|
27
|
-
sendOtpStatus: initialFetchStatus,
|
|
28
|
-
otpverificationStatus: initialFetchStatus,
|
|
29
|
-
},
|
|
30
|
-
Officer_5: {
|
|
31
|
-
localData: undefined,
|
|
32
|
-
sendOtpStatus: initialFetchStatus,
|
|
33
|
-
otpverificationStatus: initialFetchStatus,
|
|
34
|
-
},
|
|
35
|
-
Officer_6: {
|
|
36
|
-
localData: undefined,
|
|
37
|
-
sendOtpStatus: initialFetchStatus,
|
|
38
|
-
otpverificationStatus: initialFetchStatus,
|
|
39
|
-
},
|
|
40
|
-
Officer_7: {
|
|
41
|
-
localData: undefined,
|
|
42
|
-
sendOtpStatus: initialFetchStatus,
|
|
43
|
-
otpverificationStatus: initialFetchStatus,
|
|
44
|
-
},
|
|
45
|
-
Officer_8: {
|
|
46
|
-
localData: undefined,
|
|
47
|
-
sendOtpStatus: initialFetchStatus,
|
|
48
|
-
otpverificationStatus: initialFetchStatus,
|
|
49
|
-
},
|
|
50
|
-
Officer_9: {
|
|
51
|
-
localData: undefined,
|
|
52
|
-
sendOtpStatus: initialFetchStatus,
|
|
53
|
-
otpverificationStatus: initialFetchStatus,
|
|
54
|
-
},
|
|
55
|
-
Officer_10: {
|
|
56
|
-
localData: undefined,
|
|
57
|
-
sendOtpStatus: initialFetchStatus,
|
|
58
|
-
otpverificationStatus: initialFetchStatus,
|
|
59
|
-
},
|
|
16
|
+
Officer_1: { ...emptyOfficerSlot },
|
|
17
|
+
Officer_2: { ...emptyOfficerSlot },
|
|
18
|
+
Officer_3: { ...emptyOfficerSlot },
|
|
19
|
+
Officer_4: { ...emptyOfficerSlot },
|
|
20
|
+
Officer_5: { ...emptyOfficerSlot },
|
|
21
|
+
Officer_6: { ...emptyOfficerSlot },
|
|
22
|
+
Officer_7: { ...emptyOfficerSlot },
|
|
23
|
+
Officer_8: { ...emptyOfficerSlot },
|
|
24
|
+
Officer_9: { ...emptyOfficerSlot },
|
|
25
|
+
Officer_10: { ...emptyOfficerSlot },
|
|
60
26
|
},
|
|
61
27
|
primaryContactDetails: {},
|
|
62
28
|
};
|
|
@@ -297,7 +263,60 @@ const setupView = createSlice({
|
|
|
297
263
|
clearSetupView(draft) {
|
|
298
264
|
Object.assign(draft, initialState);
|
|
299
265
|
},
|
|
266
|
+
/**
|
|
267
|
+
* Merge AI-parsed officer fields into the selected officer's localData and
|
|
268
|
+
* track which field names were autofilled so the form can show the ✦ badge.
|
|
269
|
+
*/
|
|
270
|
+
applyKycDocumentAutofillForSetup: {
|
|
271
|
+
reducer(draft, action) {
|
|
272
|
+
const { officerType, values, autoFilledFieldNames } = action.payload;
|
|
273
|
+
const slot = draft.companyOfficerUpdateStatus[officerType];
|
|
274
|
+
slot.localData = Object.assign({}, slot.localData, values);
|
|
275
|
+
slot.autoFilledFields = Array.from(new Set([...slot.autoFilledFields, ...autoFilledFieldNames]));
|
|
276
|
+
},
|
|
277
|
+
prepare(payload) {
|
|
278
|
+
return { payload };
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
/**
|
|
282
|
+
* Merge AI-parsed company fields into companyDetails.localData and track
|
|
283
|
+
* which field names were autofilled.
|
|
284
|
+
*/
|
|
285
|
+
applyKybDocumentAutofillForSetup: {
|
|
286
|
+
reducer(draft, action) {
|
|
287
|
+
const { values, autoFilledFieldNames } = action.payload;
|
|
288
|
+
draft.companyDetails.localData = Object.assign({}, draft.companyDetails.localData, values);
|
|
289
|
+
draft.companyDetails.autoFilledFields = Array.from(new Set([
|
|
290
|
+
...draft.companyDetails.autoFilledFields,
|
|
291
|
+
...autoFilledFieldNames,
|
|
292
|
+
]));
|
|
293
|
+
},
|
|
294
|
+
prepare(payload) {
|
|
295
|
+
return { payload };
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
/**
|
|
299
|
+
* Wipe AI-autofill badges. If `officerType` is provided, clears only that
|
|
300
|
+
* officer; otherwise clears company details too.
|
|
301
|
+
*/
|
|
302
|
+
clearKycKybAutofillForSetup: {
|
|
303
|
+
reducer(draft, action) {
|
|
304
|
+
const { officerType } = action.payload;
|
|
305
|
+
if (officerType != null) {
|
|
306
|
+
draft.companyOfficerUpdateStatus[officerType].autoFilledFields = [];
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
draft.companyDetails.autoFilledFields = [];
|
|
310
|
+
Object.keys(draft.companyOfficerUpdateStatus).forEach((key) => {
|
|
311
|
+
draft.companyOfficerUpdateStatus[key].autoFilledFields = [];
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
prepare(payload = {}) {
|
|
316
|
+
return { payload };
|
|
317
|
+
},
|
|
318
|
+
},
|
|
300
319
|
},
|
|
301
320
|
});
|
|
302
|
-
export const { enableSetup, enableSetupSuccess, enableSetupFailure, updateBusinessVerificationDetails, updateBusinessVerificationDetailsSuccess, updateBusinessVerificationDetailsFailure, updateSelectedCompanyOfficer, updateSetupViewLocalStoreData, saveSetupViewDataInLocalStore, saveCompnayOfficerPhoneInLocalStore, saveCompnayOfficerAdditionalDocumentsInLocalStore, saveTreasuryAdditionalDocumentsInLocalStore, sendOtp: sendOtpSpendManagementSetUp, resendOtp: resendOtpSpendManagementSetUp, sendOtpSuccess: sendOtpSuccessSpendManagementSetUp, sendOtpFailure: sendOtpFailureSpendManagementSetUp, verifyOtp: verifyOtpSpendManagementSetUp, verifyOtpSuccess: verifyOtpSuccessSpendManagementSetUp, verifyOtpFailure: verifyOtpFailureSpendManagementSetUp, saveIndustryAndIncDateInLocalStore, clearSetupViewDataInLocalStore, clearSetupView, } = setupView.actions;
|
|
321
|
+
export const { enableSetup, enableSetupSuccess, enableSetupFailure, updateBusinessVerificationDetails, updateBusinessVerificationDetailsSuccess, updateBusinessVerificationDetailsFailure, updateSelectedCompanyOfficer, updateSetupViewLocalStoreData, saveSetupViewDataInLocalStore, saveCompnayOfficerPhoneInLocalStore, saveCompnayOfficerAdditionalDocumentsInLocalStore, saveTreasuryAdditionalDocumentsInLocalStore, sendOtp: sendOtpSpendManagementSetUp, resendOtp: resendOtpSpendManagementSetUp, sendOtpSuccess: sendOtpSuccessSpendManagementSetUp, sendOtpFailure: sendOtpFailureSpendManagementSetUp, verifyOtp: verifyOtpSpendManagementSetUp, verifyOtpSuccess: verifyOtpSuccessSpendManagementSetUp, verifyOtpFailure: verifyOtpFailureSpendManagementSetUp, saveIndustryAndIncDateInLocalStore, clearSetupViewDataInLocalStore, clearSetupView, applyKycDocumentAutofillForSetup, applyKybDocumentAutofillForSetup, clearKycKybAutofillForSetup, } = setupView.actions;
|
|
303
322
|
export default setupView.reducer;
|
|
@@ -119,6 +119,7 @@ export const getCompanyAndIdentityDetails = (state, companyId, companyAndIdentit
|
|
|
119
119
|
const companyAddress = addressViewState.newAddressState?.company_address;
|
|
120
120
|
const registeredCompanyAddress = addressViewState.newAddressState?.company_registered_address;
|
|
121
121
|
companyDetailsLocalData = {
|
|
122
|
+
autoFilledFields: companyDetails.autoFilledFields,
|
|
122
123
|
companyId,
|
|
123
124
|
companyDescription,
|
|
124
125
|
companyLegalName,
|
|
@@ -191,6 +192,7 @@ export const getCompanyAndIdentityDetails = (state, companyId, companyAndIdentit
|
|
|
191
192
|
const companyOfficerAddress = addressViewState.newAddressState?.[addressType];
|
|
192
193
|
companyOfficerLocalData[officerType] = {
|
|
193
194
|
...companyOfficer.localData,
|
|
195
|
+
autoFilledFields: companyOfficer.autoFilledFields,
|
|
194
196
|
userFiles: getFilesByFileIds(fileState, fileIds),
|
|
195
197
|
additionalFiles: getFilesByFileIds(fileState, additionalSubmittedDocumentsForVerificationFileIds),
|
|
196
198
|
deleteFileStatusById,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the KYC / KYB document autofill flow that lives inside the
|
|
3
|
+
* commonSetup feature (Setup pages + Onboarding both consume it via the same
|
|
4
|
+
* selector view; there is no separate state slice).
|
|
5
|
+
*
|
|
6
|
+
* Backed by document-communication-agent `POST /1.0/documents/process/sync`,
|
|
7
|
+
* which proxies document-service ExtendAI parsers and returns one of the
|
|
8
|
+
* parser payloads below — each value shaped as `{value, confidence}` per field.
|
|
9
|
+
*/
|
|
10
|
+
/** Confidence floor below which we drop an autofill candidate. */
|
|
11
|
+
export const KYC_KYB_AUTOFILL_MIN_CONFIDENCE = 0.5;
|
|
12
|
+
/**
|
|
13
|
+
* Maps the form-side {@link KycSelectDocumentType} (camelCase) to the
|
|
14
|
+
* parser-side {@link KycProvidedDocumentType} (snake_case). Returns `null` for
|
|
15
|
+
* `stateId`, which has no parser today.
|
|
16
|
+
*/
|
|
17
|
+
export const toKycProvidedDocumentType = (selectType) => {
|
|
18
|
+
switch (selectType) {
|
|
19
|
+
case 'driverLicense':
|
|
20
|
+
return 'driving_license';
|
|
21
|
+
case 'passport':
|
|
22
|
+
return 'passport';
|
|
23
|
+
case 'ssnCard':
|
|
24
|
+
return 'social_security_card';
|
|
25
|
+
case 'stateId':
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -8,6 +8,8 @@ import { getActualPaymentDate } from './helpers';
|
|
|
8
8
|
import { getApproversOrRejectors as getApproversOrRejectorsForReimbursement, } from './reimbursement/remiListView/remiListSelector';
|
|
9
9
|
import { ALL_REMI_TABS, getRemiListKey, } from './reimbursement/remiListView/remiListState';
|
|
10
10
|
//filters items against filter values representing a range. ex: date (from-to), amount(1k<-->5k)
|
|
11
|
+
// Spend Management uses only equal/not_equal — TC amount operators
|
|
12
|
+
// (inBetween, lessThan, greaterThan) live in the TC filter pipeline.
|
|
11
13
|
const filterItemOnRangeCategoryType = (valueForItem, currentFilter) => {
|
|
12
14
|
let doesItemFallInValueRange = false;
|
|
13
15
|
const filterField = currentFilter.field;
|
|
@@ -41,7 +43,7 @@ const filterItemOnCategoriesWithSingleValue = (categoryValue, currentFilter, ran
|
|
|
41
43
|
return filterItemOnRangeCategoryType(categoryValue, currentFilter);
|
|
42
44
|
}
|
|
43
45
|
// if filter category is not rangeType
|
|
44
|
-
if (currentFilter.matchingOperator === '
|
|
46
|
+
if (currentFilter.matchingOperator === 'not_equal') {
|
|
45
47
|
return currentFilter.values.indexOf(categoryValue.toString()) === -1;
|
|
46
48
|
}
|
|
47
49
|
return currentFilter.values.indexOf(categoryValue.toString()) > -1;
|
|
@@ -115,7 +117,7 @@ export const applyAdvancedFiltersOnList = (entity, allItems, filters, filteredIt
|
|
|
115
117
|
? getCategoryValueForTaskList(key, item)
|
|
116
118
|
: getCategoryValueForPaymentHistory(key, item);
|
|
117
119
|
if (categoryValue == null) {
|
|
118
|
-
if (currentFilter.matchingOperator === '
|
|
120
|
+
if (currentFilter.matchingOperator === 'not_equal') {
|
|
119
121
|
return true;
|
|
120
122
|
}
|
|
121
123
|
return false;
|
|
@@ -208,7 +208,7 @@ const applyAdvancedFiltersOnCompaniesList = (allCompanies, filters, filteredComp
|
|
|
208
208
|
const key = currentFilter.field;
|
|
209
209
|
const categoryValue = getCategoryValueForCompany(key, company);
|
|
210
210
|
if (categoryValue == null) {
|
|
211
|
-
if (currentFilter.matchingOperator === '
|
|
211
|
+
if (currentFilter.matchingOperator === 'not_equal') {
|
|
212
212
|
return true;
|
|
213
213
|
}
|
|
214
214
|
return false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { of } from 'rxjs';
|
|
2
|
-
import { catchError, filter,
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
4
|
import { mapCannedResponsePayloadToCannedResponse, } from '../cannedResponsesPayload';
|
|
5
5
|
import { fetchCannedResponses, updateCannedResponses, updateCannedResponsesFetchStatus, } from '../cannedResponsesReducer';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { of } from 'rxjs';
|
|
2
|
-
import { catchError, filter,
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
4
|
import { fetchCannedResponses, saveCannedResponse, saveCannedResponseFailure, saveCannedResponseSuccess, } from '../cannedResponsesReducer';
|
|
5
5
|
export const saveCannedResponseEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(saveCannedResponse.match), switchMap((action) => {
|
|
@@ -4,7 +4,7 @@ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
|
4
4
|
import { updateTasks } from '../../../../entity/task/taskReducer';
|
|
5
5
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
6
6
|
import { fetchTaskList, removeTaskFromList, } from '../../taskListView/taskListReducer';
|
|
7
|
-
import { snoozeTaskSuccessOrFailure, unsnoozeTask
|
|
7
|
+
import { snoozeTaskSuccessOrFailure, unsnoozeTask } from '../taskDetailReducer';
|
|
8
8
|
export const unsnoozeTaskEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(unsnoozeTask.match), mergeMap((action) => handleUnsnoozeTask(action.payload.taskId, zeniAPI)));
|
|
9
9
|
const handleUnsnoozeTask = (taskId, zeniAPI) => {
|
|
10
10
|
const unsnoozeTaskApi$ = zeniAPI.deleteAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks/${taskId}/snooze`);
|
|
@@ -238,12 +238,34 @@ const transactionDetail = createSlice({
|
|
|
238
238
|
saveTransactionDetailLocalData(draft, action) {
|
|
239
239
|
const key = getTransactionDetailKey(action.payload.transactionId);
|
|
240
240
|
const detail = recordGet(draft.transactionDetailById, key, undefined);
|
|
241
|
-
if (detail
|
|
242
|
-
|
|
243
|
-
...detail,
|
|
244
|
-
transactionDetailLocalData: action.payload.transactionLocalData,
|
|
245
|
-
};
|
|
241
|
+
if (detail == null) {
|
|
242
|
+
return;
|
|
246
243
|
}
|
|
244
|
+
const incoming = action.payload.transactionLocalData;
|
|
245
|
+
const prevById = detail.transactionDetailLocalData.lineItemById;
|
|
246
|
+
// Per-line `categoryClassRecommendationsFetchState` is owned by the
|
|
247
|
+
// recommendation epic/reducers (markInProgress / markCompleted /
|
|
248
|
+
// markFailure / setEntityRecommendationForLineIdsForTransactionDetail).
|
|
249
|
+
// Callers that rebuild `transactionLocalData` from a UI snapshot will
|
|
250
|
+
// typically have an out-of-date copy of this field (e.g. payee-change
|
|
251
|
+
// captures the snapshot before the epic's start arm runs and would
|
|
252
|
+
// otherwise clobber In-Progress back to undefined). Treat the field as
|
|
253
|
+
// sticky: only let the caller override it when they explicitly set it.
|
|
254
|
+
const mergedLineItemById = {};
|
|
255
|
+
Object.entries(incoming.lineItemById ?? {}).forEach(([lineId, line]) => {
|
|
256
|
+
mergedLineItemById[lineId] = {
|
|
257
|
+
...line,
|
|
258
|
+
categoryClassRecommendationsFetchState: line.categoryClassRecommendationsFetchState ??
|
|
259
|
+
prevById?.[lineId]?.categoryClassRecommendationsFetchState,
|
|
260
|
+
};
|
|
261
|
+
});
|
|
262
|
+
draft.transactionDetailById[key] = {
|
|
263
|
+
...detail,
|
|
264
|
+
transactionDetailLocalData: {
|
|
265
|
+
...incoming,
|
|
266
|
+
lineItemById: mergedLineItemById,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
247
269
|
},
|
|
248
270
|
saveTransactionDetail(draft, action) {
|
|
249
271
|
const key = getTransactionDetailKey(action.payload.transactionId);
|
|
@@ -365,6 +387,21 @@ const transactionDetail = createSlice({
|
|
|
365
387
|
const detail = recordGet(draft.transactionDetailById, key, undefined);
|
|
366
388
|
if (detail != null) {
|
|
367
389
|
const newLocalData = setEntityRecommendationForLineIdInLocalData(transaction, detail.transactionDetailLocalData, action.payload.entity, lineIds, uncategorizedIncomeExpense, recommendationWithCOTByLineId);
|
|
390
|
+
// Release the per-line fetch flag for every line this fetch
|
|
391
|
+
// covered so the inline skeleton resolves and the page-level
|
|
392
|
+
// Save button can re-enable.
|
|
393
|
+
lineIds.forEach((lineId) => {
|
|
394
|
+
const lineItem = newLocalData.lineItemById[lineId];
|
|
395
|
+
if (lineItem != null) {
|
|
396
|
+
newLocalData.lineItemById[lineId] = {
|
|
397
|
+
...lineItem,
|
|
398
|
+
categoryClassRecommendationsFetchState: {
|
|
399
|
+
fetchState: 'Completed',
|
|
400
|
+
error: undefined,
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
});
|
|
368
405
|
draft.transactionDetailById[key] = {
|
|
369
406
|
...detail,
|
|
370
407
|
transactionDetailLocalData: newLocalData,
|
|
@@ -385,6 +422,84 @@ const transactionDetail = createSlice({
|
|
|
385
422
|
};
|
|
386
423
|
},
|
|
387
424
|
},
|
|
425
|
+
// Start arm of the line-update recommendations fetch for the detail
|
|
426
|
+
// page. Flips covered lines to In-Progress; detail page has no
|
|
427
|
+
// checkbox, so no auto-uncheck side effect.
|
|
428
|
+
markCategoryClassRecommendationsInProgressForTransactionDetail: {
|
|
429
|
+
reducer(draft, action) {
|
|
430
|
+
const { transactionId, lineIds } = action.payload;
|
|
431
|
+
const key = getTransactionDetailKey(transactionId);
|
|
432
|
+
const detail = recordGet(draft.transactionDetailById, key, undefined);
|
|
433
|
+
if (detail != null) {
|
|
434
|
+
lineIds.forEach((lineId) => {
|
|
435
|
+
const lineItem = detail.transactionDetailLocalData.lineItemById[lineId];
|
|
436
|
+
if (lineItem != null) {
|
|
437
|
+
detail.transactionDetailLocalData.lineItemById[lineId] = {
|
|
438
|
+
...lineItem,
|
|
439
|
+
categoryClassRecommendationsFetchState: {
|
|
440
|
+
fetchState: 'In-Progress',
|
|
441
|
+
error: undefined,
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
prepare(transactionId, lineIds) {
|
|
449
|
+
return { payload: { transactionId, lineIds } };
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
// Completed arm. Used when the HTTP call succeeded but the server
|
|
453
|
+
// returned no per-line recommendations — still need to release the
|
|
454
|
+
// In-Progress flag.
|
|
455
|
+
markCategoryClassRecommendationsCompletedForTransactionDetail: {
|
|
456
|
+
reducer(draft, action) {
|
|
457
|
+
const { transactionId, lineIds } = action.payload;
|
|
458
|
+
const key = getTransactionDetailKey(transactionId);
|
|
459
|
+
const detail = recordGet(draft.transactionDetailById, key, undefined);
|
|
460
|
+
if (detail != null) {
|
|
461
|
+
lineIds.forEach((lineId) => {
|
|
462
|
+
const lineItem = detail.transactionDetailLocalData.lineItemById[lineId];
|
|
463
|
+
if (lineItem != null) {
|
|
464
|
+
detail.transactionDetailLocalData.lineItemById[lineId] = {
|
|
465
|
+
...lineItem,
|
|
466
|
+
categoryClassRecommendationsFetchState: {
|
|
467
|
+
fetchState: 'Completed',
|
|
468
|
+
error: undefined,
|
|
469
|
+
},
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
prepare(transactionId, lineIds) {
|
|
476
|
+
return { payload: { transactionId, lineIds } };
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
markCategoryClassRecommendationsFailureForTransactionDetail: {
|
|
480
|
+
reducer(draft, action) {
|
|
481
|
+
const { transactionId, lineIds, error } = action.payload;
|
|
482
|
+
const key = getTransactionDetailKey(transactionId);
|
|
483
|
+
const detail = recordGet(draft.transactionDetailById, key, undefined);
|
|
484
|
+
if (detail != null) {
|
|
485
|
+
lineIds.forEach((lineId) => {
|
|
486
|
+
const lineItem = detail.transactionDetailLocalData.lineItemById[lineId];
|
|
487
|
+
if (lineItem != null) {
|
|
488
|
+
detail.transactionDetailLocalData.lineItemById[lineId] = {
|
|
489
|
+
...lineItem,
|
|
490
|
+
categoryClassRecommendationsFetchState: {
|
|
491
|
+
fetchState: 'Error',
|
|
492
|
+
error,
|
|
493
|
+
},
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
prepare(transactionId, lineIds, error) {
|
|
500
|
+
return { payload: { transactionId, lineIds, error } };
|
|
501
|
+
},
|
|
502
|
+
},
|
|
388
503
|
removeEntityRecommendationForLineIdForTransactionDetail: {
|
|
389
504
|
reducer(draft, action) {
|
|
390
505
|
const { transaction, lineId } = action.payload;
|
|
@@ -656,7 +771,7 @@ const transactionDetail = createSlice({
|
|
|
656
771
|
},
|
|
657
772
|
},
|
|
658
773
|
});
|
|
659
|
-
export const { downloadAccountingProviderAttachment, downloadAccountingProviderAttachmentSuccess, downloadAccountingProviderAttachmentFailure, fetchTransactionDetail, updateTransactionDetailFetchState, removeTransactionDetail, clearTransactionDetail, uploadMissingAttachmentSuccess, updateTransactionDetail, updateTransactionDetailSaveStatus, clearTransactionDetailSaveStatus, markTransactionAsNotMiscategorized, deleteTransactionAttachment, deleteTransactionAttachmentFailure, deleteTransactionAttachmentSuccess, updateStatusForTransactionNotMiscategorizedUpdate, updateStatusConsolidatedSaveTransactionDetail, updateTransactionStateIfUpdateActionNotAllowed, saveTransactionDetail, initializeTransactionDetailLocalData, saveTransactionDetailLocalData, clearTransactionDetailLocalData, resetLineItemsCategoryClassInLocalData, setAllLineItemsToCategoryClassInLocalData, setAllLineItemsLocalDataIsUpdateAllChecked, setEntityRecommendationForLineIdsForTransactionDetail, removeEntityRecommendationForLineIdForTransactionDetail, updateSelectedVendor, updateSelectedCustomer, resetVendor, resetSelectedCustomer, updateLocalDataWithTransactionsUpdateWithVendorCheckbox, updateVendorToAllLineItems, resetAllLineItemsToVendor, updateLatestSelectedEntity, updateVendorBulkRecommendationsFetchStatus, setIsVendorUpdateAllChecked, } = transactionDetail.actions;
|
|
774
|
+
export const { downloadAccountingProviderAttachment, downloadAccountingProviderAttachmentSuccess, downloadAccountingProviderAttachmentFailure, fetchTransactionDetail, updateTransactionDetailFetchState, removeTransactionDetail, clearTransactionDetail, uploadMissingAttachmentSuccess, updateTransactionDetail, updateTransactionDetailSaveStatus, clearTransactionDetailSaveStatus, markTransactionAsNotMiscategorized, deleteTransactionAttachment, deleteTransactionAttachmentFailure, deleteTransactionAttachmentSuccess, updateStatusForTransactionNotMiscategorizedUpdate, updateStatusConsolidatedSaveTransactionDetail, updateTransactionStateIfUpdateActionNotAllowed, saveTransactionDetail, initializeTransactionDetailLocalData, saveTransactionDetailLocalData, clearTransactionDetailLocalData, resetLineItemsCategoryClassInLocalData, setAllLineItemsToCategoryClassInLocalData, setAllLineItemsLocalDataIsUpdateAllChecked, setEntityRecommendationForLineIdsForTransactionDetail, markCategoryClassRecommendationsInProgressForTransactionDetail, markCategoryClassRecommendationsCompletedForTransactionDetail, markCategoryClassRecommendationsFailureForTransactionDetail, removeEntityRecommendationForLineIdForTransactionDetail, updateSelectedVendor, updateSelectedCustomer, resetVendor, resetSelectedCustomer, updateLocalDataWithTransactionsUpdateWithVendorCheckbox, updateVendorToAllLineItems, resetAllLineItemsToVendor, updateLatestSelectedEntity, updateVendorBulkRecommendationsFetchStatus, setIsVendorUpdateAllChecked, } = transactionDetail.actions;
|
|
660
775
|
export default transactionDetail.reducer;
|
|
661
776
|
function getUpdatedEntityLocalData(detail, updates, entity, resetRecommendations, type) {
|
|
662
777
|
const key = type === 'customer' ? 'customerUpdates' : 'vendorUpdates';
|