@zeniai/client-epic-state 5.0.52 → 5.0.53-betaML4
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/recommendationBase.d.ts +2 -1
- package/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
- package/lib/commonStateTypes/viewAndReport/viewAndReport.js +1 -0
- package/lib/entity/account/accountState.d.ts +1 -1
- package/lib/entity/accountGroup/accountGroupState.d.ts +1 -1
- package/lib/entity/class/classReducer.d.ts +4 -4
- package/lib/entity/class/classState.d.ts +1 -1
- package/lib/entity/forecast/forecastState.d.ts +1 -1
- package/lib/entity/project/projectPayload.d.ts +8 -1
- package/lib/entity/project/projectPayload.js +15 -1
- package/lib/entity/project/projectState.d.ts +4 -2
- package/lib/entity/sectionAccountsView/sectionAccountsView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesViewReducer.d.ts +2 -2
- package/lib/entity/sectionProjectView/sectionProjectView.d.ts +1 -1
- package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +2 -2
- package/lib/entity/tenant/clearAllEpic.d.ts +2 -1
- package/lib/entity/tenant/clearAllEpic.js +2 -0
- package/lib/entity/transaction/payloadTypes/transactionLinePayload.d.ts +2 -0
- package/lib/entity/transaction/payloadTypes/transactionLinePayload.js +9 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +2 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.js +6 -0
- package/lib/entity/transaction/stateTypes/transaction.d.ts +2 -0
- package/lib/entity/transaction/stateTypes/transactionLine.d.ts +2 -0
- package/lib/epic.d.ts +4 -1
- package/lib/epic.js +5 -1
- package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +1 -0
- package/lib/esm/entity/project/projectPayload.js +12 -0
- package/lib/esm/entity/tenant/clearAllEpic.js +2 -0
- package/lib/esm/entity/transaction/payloadTypes/transactionLinePayload.js +9 -0
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +6 -0
- package/lib/esm/epic.js +5 -1
- package/lib/esm/index.js +11 -7
- package/lib/esm/reducer.js +3 -0
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +8 -0
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic.js +3 -0
- package/lib/esm/view/expenseAutomationView/helpers/saveTransactionHelper.js +1 -0
- package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +11 -2
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +127 -31
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +13 -2
- package/lib/esm/view/expenseAutomationView/types/transactionsViewState.js +1 -0
- package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +44 -0
- package/lib/esm/view/projectList/fetchProjectListEpic.js +38 -0
- package/lib/esm/view/projectList/projectListPayload.js +1 -0
- package/lib/esm/view/projectList/projectListReducer.js +39 -0
- package/lib/esm/view/projectList/projectListSelector.js +9 -0
- package/lib/esm/view/projectList/projectListState.js +1 -0
- package/lib/esm/view/recommendation/fetchEntityRecommendationsForCategorizationEpic.js +83 -0
- package/lib/esm/view/recommendation/recommendationReducer.js +52 -1
- package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +1 -0
- package/lib/esm/view/transactionDetail/epics/transactionDetailEpic.js +6 -0
- package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +3 -0
- package/lib/esm/view/transactionDetail/transactionDetailSelector.js +14 -2
- package/lib/esm/view/transactionList/fetchTransactionListByProjectEpic.js +45 -0
- package/lib/esm/view/transactionList/parallelFetchProjectTransactionListEpic.js +32 -0
- package/lib/esm/view/transactionList/transactionListByProjectSelector.js +58 -0
- package/lib/esm/view/transactionList/transactionListReducer.js +83 -2
- package/lib/esm/view/transactionList/transactionListState.js +10 -0
- package/lib/index.d.ts +13 -9
- package/lib/index.js +42 -27
- package/lib/reducer.d.ts +3 -0
- package/lib/reducer.js +3 -0
- package/lib/tsconfig.typecheck.tsbuildinfo +1 -0
- package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
- package/lib/view/billPayCard/billPayCardSelector.d.ts +1 -1
- package/lib/view/cardBalance/cardBalanceSelector.d.ts +1 -1
- package/lib/view/cashBalance/cashBalanceSelector.d.ts +1 -1
- package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +1 -1
- package/lib/view/cashPosition/cashPositionSelector.d.ts +1 -1
- package/lib/view/dashboard/dashboardReducer.d.ts +2 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.d.ts +2 -1
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +8 -0
- package/lib/view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic.js +3 -0
- package/lib/view/expenseAutomationView/helpers/saveTransactionHelper.js +1 -0
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +2 -1
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +11 -2
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +3 -1
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +127 -31
- package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +4 -0
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -1
- package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +5 -1
- package/lib/view/expenseAutomationView/types/transactionsViewState.js +1 -0
- package/lib/view/financeStatement/financeStatementReducer.d.ts +1 -1
- package/lib/view/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
- package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.d.ts +15 -1
- package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +45 -0
- package/lib/view/projectList/fetchProjectListEpic.d.ts +8 -0
- package/lib/view/projectList/fetchProjectListEpic.js +42 -0
- package/lib/view/projectList/projectListPayload.d.ts +7 -0
- package/lib/view/projectList/projectListPayload.js +2 -0
- package/lib/view/projectList/projectListReducer.d.ts +9 -0
- package/lib/view/projectList/projectListReducer.js +43 -0
- package/lib/view/projectList/projectListSelector.d.ts +8 -0
- package/lib/view/projectList/projectListSelector.js +13 -0
- package/lib/view/projectList/projectListState.d.ts +4 -0
- package/lib/view/projectList/projectListState.js +2 -0
- package/lib/view/recommendation/fetchEntityRecommendationsForCategorizationEpic.d.ts +8 -0
- package/lib/view/recommendation/fetchEntityRecommendationsForCategorizationEpic.js +87 -0
- package/lib/view/recommendation/recommendationReducer.d.ts +21 -1
- package/lib/view/recommendation/recommendationReducer.js +53 -2
- package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
- package/lib/view/reportsResync/reportsResyncReducer.d.ts +2 -2
- package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
- package/lib/view/topEx/topExSelector.d.ts +1 -1
- package/lib/view/transactionDetail/epics/saveTransactionHelper.js +1 -0
- package/lib/view/transactionDetail/epics/transactionDetailEpic.d.ts +2 -1
- package/lib/view/transactionDetail/epics/transactionDetailEpic.js +6 -0
- package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +3 -0
- package/lib/view/transactionDetail/transactionDetailSelector.d.ts +3 -0
- package/lib/view/transactionDetail/transactionDetailSelector.js +13 -1
- package/lib/view/transactionDetail/transactionDetailState.d.ts +2 -0
- package/lib/view/transactionDetail/transactionDetailTypes.d.ts +2 -0
- package/lib/view/transactionList/fetchTransactionListByProjectEpic.d.ts +8 -0
- package/lib/view/transactionList/fetchTransactionListByProjectEpic.js +52 -0
- package/lib/view/transactionList/parallelFetchProjectTransactionListEpic.d.ts +6 -0
- package/lib/view/transactionList/parallelFetchProjectTransactionListEpic.js +36 -0
- package/lib/view/transactionList/transactionListByProjectSelector.d.ts +22 -0
- package/lib/view/transactionList/transactionListByProjectSelector.js +66 -0
- package/lib/view/transactionList/transactionListPayload.d.ts +15 -0
- package/lib/view/transactionList/transactionListReducer.d.ts +25 -2
- package/lib/view/transactionList/transactionListReducer.js +83 -2
- package/lib/view/transactionList/transactionListState.d.ts +15 -0
- package/lib/view/transactionList/transactionListState.js +13 -1
- package/package.json +1 -1
|
@@ -12,9 +12,10 @@ const transactionHelper_1 = require("../../../entity/transaction/transactionHelp
|
|
|
12
12
|
const transactionSelector_1 = require("../../../entity/transaction/transactionSelector");
|
|
13
13
|
const accountListSelector_1 = require("../../accountList/accountListSelector");
|
|
14
14
|
const classListSelector_1 = require("../../classList/classListSelector");
|
|
15
|
+
const projectListSelector_1 = require("../../projectList/projectListSelector");
|
|
15
16
|
const expenseAutomationViewSelectorTypes_1 = require("../selectorTypes/expenseAutomationViewSelectorTypes");
|
|
16
17
|
function getExpenseAutomationTransactionView(state) {
|
|
17
|
-
const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
|
|
18
|
+
const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, projectState, projectListState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
|
|
18
19
|
const { selectedTransactionCategorizationTab } = expenseAutomationTransactionsViewState;
|
|
19
20
|
const { uiState, refreshStatus, saveStatus, markAsNotMiscategorizedStatus, transactionIdsBySelectedPeriod, transactionReviewLocalDataById, selectedCheckBoxTransactionIds, transactionIdsWithUnsavedData, uploadReceiptStatusById, selectedTransactionId, selectedTransactionLineId, } = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab];
|
|
20
21
|
const uncategorizedIncomeExpense = (0, accountListSelector_1.getUncategorizedAccounts)(accountState, accountListState, 'accountList');
|
|
@@ -23,6 +24,8 @@ function getExpenseAutomationTransactionView(state) {
|
|
|
23
24
|
const allClasses = classList.classes.map((classData) => {
|
|
24
25
|
return (0, omit_1.default)(classData, ['accountIds', 'key']);
|
|
25
26
|
});
|
|
27
|
+
const projectList = (0, projectListSelector_1.getProjectList)(projectState, projectListState);
|
|
28
|
+
const isAccountingProjectsEnabled = (0, tenantSelector_1.getIsAccountingProjectsEnabled)(state);
|
|
26
29
|
const accountsHierarchyList = (0, accountListSelector_1.getNestedAccountListHierarchy)(accountListState, 'accountList');
|
|
27
30
|
const classHierarchyList = (0, classListSelector_1.getNestedClassListHierarchy)(classListState);
|
|
28
31
|
const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
|
|
@@ -45,6 +48,11 @@ function getExpenseAutomationTransactionView(state) {
|
|
|
45
48
|
return null;
|
|
46
49
|
})
|
|
47
50
|
.filter((transaction) => transaction != null);
|
|
51
|
+
// True if any visible line is currently fetching category/class
|
|
52
|
+
// recommendations because the user changed the payee. Used to disable Save
|
|
53
|
+
// and to defer manual checkbox selection.
|
|
54
|
+
const hasInFlightCategoryClassRecommendations = transactionLocalData.some((transaction) => Object.values(transaction.transactionReviewLocalData.lineItemById).some((lineItem) => lineItem.categoryClassRecommendationsFetchState?.fetchState ===
|
|
55
|
+
'In-Progress'));
|
|
48
56
|
const transactions = (0, transactionSelector_1.getSupportedTransactionsByIds)(transactionState, transactionIds);
|
|
49
57
|
const transactionsWithCOT = transactions.map((transaction) => (0, transactionHelper_1.getTransactionWithCOT)(transaction));
|
|
50
58
|
const monthEndFetchState = monthYearPeriodId != null
|
|
@@ -102,6 +110,8 @@ function getExpenseAutomationTransactionView(state) {
|
|
|
102
110
|
classList: allClasses,
|
|
103
111
|
accountsHierarchyList,
|
|
104
112
|
classHierarchyList,
|
|
113
|
+
isAccountingProjectsEnabled,
|
|
114
|
+
projectList,
|
|
105
115
|
transactionLocalData,
|
|
106
116
|
uiState,
|
|
107
117
|
refreshStatus,
|
|
@@ -113,5 +123,6 @@ function getExpenseAutomationTransactionView(state) {
|
|
|
113
123
|
uploadReceiptStatusById,
|
|
114
124
|
selectedTransactionId,
|
|
115
125
|
selectedTransactionLineId,
|
|
126
|
+
hasInFlightCategoryClassRecommendations,
|
|
116
127
|
};
|
|
117
128
|
}
|
|
@@ -7,6 +7,7 @@ import { PageToken } from '../../../commonStateTypes/viewAndReport/viewAndReport
|
|
|
7
7
|
import { AccountBase } from '../../../entity/account/accountState';
|
|
8
8
|
import { ClassBase } from '../../../entity/class/classState';
|
|
9
9
|
import { CustomerBase } from '../../../entity/customer/customerState';
|
|
10
|
+
import { ProjectBase } from '../../../entity/project/projectState';
|
|
10
11
|
import { Entity, EntityType } from '../../../entity/genericEntity/entity';
|
|
11
12
|
import { TransactionID } from '../../../entity/transaction/stateTypes/transaction';
|
|
12
13
|
import { BillableStatus, CategorizationStatusType, PlatformLineDetailType, ProductOrService, TransactionLineBase } from '../../../entity/transaction/stateTypes/transactionLine';
|
|
@@ -15,7 +16,7 @@ import { VendorBase } from '../../../entity/vendor/vendorState';
|
|
|
15
16
|
import { ZeniDate } from '../../../zeniDayJS';
|
|
16
17
|
import { EntityRecommendationKey } from '../../recommendation/recommendationState';
|
|
17
18
|
import { TransactionDetailKey } from '../../transactionDetail/transactionDetailState';
|
|
18
|
-
export declare const toTransactionsSortKey: (v: string) => "date" | "amount" | "vendor" | "category" | "class" | "payment_account" | "transaction_type" | "memo_and_receipt";
|
|
19
|
+
export declare const toTransactionsSortKey: (v: string) => "date" | "amount" | "vendor" | "project" | "category" | "class" | "payment_account" | "transaction_type" | "memo_and_receipt";
|
|
19
20
|
export type TransactionsSortKey = ReturnType<typeof toTransactionsSortKey>;
|
|
20
21
|
export declare const TRANSACTIONS_TABS: readonly ["review", "autoCategorized"];
|
|
21
22
|
export declare const toTransactionsTabKey: (v: string) => "review" | "autoCategorized";
|
|
@@ -45,6 +46,7 @@ export interface TransactionCategorizationLineItemData extends TransactionLineBa
|
|
|
45
46
|
transactionId: ID;
|
|
46
47
|
account?: AccountBase;
|
|
47
48
|
categorizationStatus?: CategorizationStatusType;
|
|
49
|
+
categoryClassRecommendationsFetchState?: FetchStateAndError;
|
|
48
50
|
class?: ClassBase;
|
|
49
51
|
customer?: CustomerBase;
|
|
50
52
|
item?: ProductOrService;
|
|
@@ -53,6 +55,7 @@ export interface TransactionCategorizationLineItemData extends TransactionLineBa
|
|
|
53
55
|
lineTransactionType?: TransactionType;
|
|
54
56
|
postingType?: TransactionCategory;
|
|
55
57
|
postingTypeName?: string;
|
|
58
|
+
project?: ProjectBase;
|
|
56
59
|
recommendationsWithCOT?: RecommendationWithCOT[];
|
|
57
60
|
reviewPendingReasons?: string[];
|
|
58
61
|
selectedEntityLine?: Entity;
|
|
@@ -110,6 +113,7 @@ export interface TransactionLineUpdates {
|
|
|
110
113
|
class?: ClassBase;
|
|
111
114
|
customer?: CustomerBase;
|
|
112
115
|
lineDescription?: string;
|
|
116
|
+
project?: ProjectBase;
|
|
113
117
|
recommendation?: Recommendation[];
|
|
114
118
|
vendor?: VendorBase;
|
|
115
119
|
}
|
|
@@ -17,7 +17,7 @@ export declare const fetchFinanceStatement: import("@reduxjs/toolkit").ActionCre
|
|
|
17
17
|
firstMonthOfFY: Month;
|
|
18
18
|
maxNumOfPeriodsToHighlight: number;
|
|
19
19
|
thisPeriod: TimeframeTick;
|
|
20
|
-
}, "financeStatement/updateFinanceStatementThisPeriod">, updateCOABalancesRange: import("@reduxjs/toolkit").ActionCreatorWithPayload<COABalancesRange, "financeStatement/updateCOABalancesRange">, updateSelectedReportId: import("@reduxjs/toolkit").ActionCreatorWithPayload<"cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation", "financeStatement/updateSelectedReportId">, updateFinanceStatementAdditionalBalancesSelection: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
20
|
+
}, "financeStatement/updateFinanceStatementThisPeriod">, updateCOABalancesRange: import("@reduxjs/toolkit").ActionCreatorWithPayload<COABalancesRange, "financeStatement/updateCOABalancesRange">, updateSelectedReportId: import("@reduxjs/toolkit").ActionCreatorWithPayload<"cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation", "financeStatement/updateSelectedReportId">, updateFinanceStatementAdditionalBalancesSelection: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
21
21
|
additionalBalances: COABalanceType[];
|
|
22
22
|
coaBalances: COABalance[];
|
|
23
23
|
firstMonthOfFY: Month;
|
|
@@ -3,9 +3,9 @@ import { ZeniAPIStatus } from '../../responsePayload';
|
|
|
3
3
|
import { VendorReviewViewAllRecommendationsPayload } from '../vendorReviewView/common/payload/commonTypes';
|
|
4
4
|
import { GlobalMerchantViewState, GlobalRecommendationFetchSource, NewGlobalMerchantCurrentSelection } from './globalMerchantViewState';
|
|
5
5
|
export declare const initialState: GlobalMerchantViewState;
|
|
6
|
-
export declare const createGlobalMerchant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[merchantId?: string | undefined, context?: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation" | undefined], {
|
|
6
|
+
export declare const createGlobalMerchant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[merchantId?: string | undefined, context?: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation" | undefined], {
|
|
7
7
|
merchantId: string | undefined;
|
|
8
|
-
context: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation" | undefined;
|
|
8
|
+
context: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation" | undefined;
|
|
9
9
|
}, "globalMerchantView/createGlobalMerchant", never, never>, createGlobalMerchantSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
10
10
|
merchantId: ID;
|
|
11
11
|
}, "globalMerchantView/createGlobalMerchantSuccess">, createGlobalMerchantFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { COABalance } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
2
|
+
import { HorizontalAccountRow, ProfitAndLossByClassHorizontalReport } from './profitAndLossClassesByClassHorizontalSelectorTypes';
|
|
2
3
|
/**
|
|
3
4
|
* Populates `sectionHeaderBalancesSlice`, and per-account `accountReportData`, so the
|
|
4
5
|
* web layer only maps selector output to tree nodes.
|
|
5
6
|
*/
|
|
6
7
|
export declare function enrichProfitAndLossByClassHorizontalReport(report: ProfitAndLossByClassHorizontalReport): void;
|
|
8
|
+
/**
|
|
9
|
+
* Sum balances across descendant accounts (recursive).
|
|
10
|
+
*
|
|
11
|
+
* Parent rows in the horizontal pivot only carry their own direct postings
|
|
12
|
+
* (zero for "container" accounts), so callers rendering "Total {parent}" rows
|
|
13
|
+
* must aggregate from descendants to get the real per-class totals.
|
|
14
|
+
*
|
|
15
|
+
* Returns one `COABalance` per class column + total (same shape as the
|
|
16
|
+
* enriched `balancesInTimeframe.balances`), with `amount` summed and `type`
|
|
17
|
+
* set to `default_with_null_balance` for zeros. Returns `[]` when no
|
|
18
|
+
* descendants have enriched data.
|
|
19
|
+
*/
|
|
20
|
+
export declare function aggregateHorizontalDescendantBalances(accounts: readonly HorizontalAccountRow[], childIndices: readonly number[], childrenByParent: Readonly<Record<number, readonly number[]>>): COABalance[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.enrichProfitAndLossByClassHorizontalReport = enrichProfitAndLossByClassHorizontalReport;
|
|
4
|
+
exports.aggregateHorizontalDescendantBalances = aggregateHorizontalDescendantBalances;
|
|
4
5
|
const currencyHelper_1 = require("../../commonStateTypes/currencyHelper");
|
|
5
6
|
const horizontalSectionEmptyBalancesSlice_1 = require("./horizontalSectionEmptyBalancesSlice");
|
|
6
7
|
const profitAndLossClassesByClassHorizontalSelectorTypes_1 = require("./profitAndLossClassesByClassHorizontalSelectorTypes");
|
|
@@ -118,6 +119,50 @@ function buildHorizontalClassColumnBalancesSlice(report, classAmounts, totalAmou
|
|
|
118
119
|
},
|
|
119
120
|
};
|
|
120
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Sum balances across descendant accounts (recursive).
|
|
124
|
+
*
|
|
125
|
+
* Parent rows in the horizontal pivot only carry their own direct postings
|
|
126
|
+
* (zero for "container" accounts), so callers rendering "Total {parent}" rows
|
|
127
|
+
* must aggregate from descendants to get the real per-class totals.
|
|
128
|
+
*
|
|
129
|
+
* Returns one `COABalance` per class column + total (same shape as the
|
|
130
|
+
* enriched `balancesInTimeframe.balances`), with `amount` summed and `type`
|
|
131
|
+
* set to `default_with_null_balance` for zeros. Returns `[]` when no
|
|
132
|
+
* descendants have enriched data.
|
|
133
|
+
*/
|
|
134
|
+
function aggregateHorizontalDescendantBalances(accounts, childIndices, childrenByParent) {
|
|
135
|
+
let template;
|
|
136
|
+
const sums = new Map();
|
|
137
|
+
const walk = (idx) => {
|
|
138
|
+
const childRow = accounts[idx];
|
|
139
|
+
const childBalances = childRow?.accountReportData?.balancesInTimeframe.balances;
|
|
140
|
+
if (childBalances != null) {
|
|
141
|
+
if (template == null) {
|
|
142
|
+
template = childBalances;
|
|
143
|
+
}
|
|
144
|
+
childBalances.forEach((b, i) => {
|
|
145
|
+
sums.set(i, (sums.get(i) ?? 0) + (b.balance.amount ?? 0));
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// Always recurse — a missing intermediate node should not prune its
|
|
149
|
+
// descendants from the aggregate.
|
|
150
|
+
const grandChildren = childrenByParent[idx] ?? [];
|
|
151
|
+
grandChildren.forEach(walk);
|
|
152
|
+
};
|
|
153
|
+
childIndices.forEach(walk);
|
|
154
|
+
if (template == null) {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
return template.map((tpl, i) => {
|
|
158
|
+
const amount = sums.get(i) ?? 0;
|
|
159
|
+
return {
|
|
160
|
+
...tpl,
|
|
161
|
+
balance: { ...tpl.balance, amount },
|
|
162
|
+
type: amount === 0 ? 'default_with_null_balance' : 'default',
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
}
|
|
121
166
|
/**
|
|
122
167
|
* Parent index per DFS row — O(n). Matches the scan in the former
|
|
123
168
|
* `findHorizontalAccountParentIndex` (depth <= 2 rows have no parent).
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { updateProjects } from '../../entity/project/projectReducer';
|
|
4
|
+
import { RootState } from '../../reducer';
|
|
5
|
+
import { ZeniAPI } from '../../zeniAPI';
|
|
6
|
+
import { fetchProjectList, updateProjectList, updateProjectListFailure } from './projectListReducer';
|
|
7
|
+
export type ActionType = ReturnType<typeof fetchProjectList> | ReturnType<typeof updateProjects> | ReturnType<typeof updateProjectList> | ReturnType<typeof updateProjectListFailure>;
|
|
8
|
+
export declare const fetchProjectListEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchProjectListEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const projectReducer_1 = require("../../entity/project/projectReducer");
|
|
7
|
+
const tenantSelector_1 = require("../../entity/tenant/tenantSelector");
|
|
8
|
+
const responsePayload_1 = require("../../responsePayload");
|
|
9
|
+
const projectListReducer_1 = require("./projectListReducer");
|
|
10
|
+
const buildProjectListQuery = (isIncludeDeleted) => {
|
|
11
|
+
const query = {
|
|
12
|
+
is_deleted: isIncludeDeleted,
|
|
13
|
+
sort_by: 'project_name',
|
|
14
|
+
sort_order: 'asc',
|
|
15
|
+
is_full: true,
|
|
16
|
+
};
|
|
17
|
+
return `?query=${encodeURIComponent(JSON.stringify(query))}`;
|
|
18
|
+
};
|
|
19
|
+
const fetchProjectListEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(projectListReducer_1.fetchProjectList.match), (0, operators_1.withLatestFrom)(state$), (0, operators_1.switchMap)(([action, state]) => {
|
|
20
|
+
if (!(0, tenantSelector_1.getIsAccountingProjectsEnabled)(state)) {
|
|
21
|
+
return (0, rxjs_1.of)((0, projectListReducer_1.updateProjectList)({
|
|
22
|
+
status: (0, responsePayload_1.createZeniAPIStatus)('Success', ''),
|
|
23
|
+
data: { projects: [] },
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
const { isIncludeDeleted } = action.payload;
|
|
27
|
+
const queryParams = buildProjectListQuery(isIncludeDeleted);
|
|
28
|
+
return zeniAPI
|
|
29
|
+
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/projects${queryParams}`)
|
|
30
|
+
.pipe((0, operators_1.mergeMap)((response) => {
|
|
31
|
+
if ((0, responsePayload_1.isSuccessResponse)(response)) {
|
|
32
|
+
return (0, rxjs_1.of)((0, projectReducer_1.updateProjects)(response.data?.projects ?? []), (0, projectListReducer_1.updateProjectList)(response));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return (0, rxjs_1.of)((0, projectListReducer_1.updateProjectListFailure)(response.status));
|
|
36
|
+
}
|
|
37
|
+
}), (0, operators_1.catchError)((error) => {
|
|
38
|
+
return (0, rxjs_1.of)((0, projectListReducer_1.updateProjectListFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch Projects REST API call errored out' +
|
|
39
|
+
JSON.stringify(error))));
|
|
40
|
+
}));
|
|
41
|
+
}));
|
|
42
|
+
exports.fetchProjectListEpic = fetchProjectListEpic;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ProjectMetadataPayload } from '../../entity/project/projectPayload';
|
|
2
|
+
import { ZeniAPIResponse } from '../../responsePayload';
|
|
3
|
+
interface ProjectListPayloadData {
|
|
4
|
+
projects: ProjectMetadataPayload[];
|
|
5
|
+
}
|
|
6
|
+
export type ProjectListResponse = ZeniAPIResponse<ProjectListPayloadData>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ZeniAPIStatus } from '../../responsePayload';
|
|
2
|
+
import { ProjectListResponse } from './projectListPayload';
|
|
3
|
+
import { ProjectListState } from './projectListState';
|
|
4
|
+
export declare const initialState: ProjectListState;
|
|
5
|
+
export declare const fetchProjectList: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[isIncludeDeleted?: boolean | undefined], {
|
|
6
|
+
isIncludeDeleted: boolean;
|
|
7
|
+
}, "projectList/fetchProjectList", never, never>, updateProjectList: import("@reduxjs/toolkit").ActionCreatorWithPayload<ProjectListResponse, "projectList/updateProjectList">, updateProjectListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "projectList/updateProjectListFailure">, clearProjectList: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"projectList/clearProjectList">;
|
|
8
|
+
declare const _default: import("redux").Reducer<ProjectListState>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.clearProjectList = exports.updateProjectListFailure = exports.updateProjectList = exports.fetchProjectList = exports.initialState = void 0;
|
|
5
|
+
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
|
+
exports.initialState = {
|
|
7
|
+
fetchState: 'Not-Started',
|
|
8
|
+
error: undefined,
|
|
9
|
+
projectIds: [],
|
|
10
|
+
hasValidState() {
|
|
11
|
+
return this.fetchState == 'Completed';
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
const projectList = (0, toolkit_1.createSlice)({
|
|
15
|
+
name: 'projectList',
|
|
16
|
+
initialState: exports.initialState,
|
|
17
|
+
reducers: {
|
|
18
|
+
fetchProjectList: {
|
|
19
|
+
reducer(draft) {
|
|
20
|
+
draft.fetchState = 'In-Progress';
|
|
21
|
+
draft.error = undefined;
|
|
22
|
+
},
|
|
23
|
+
prepare(isIncludeDeleted) {
|
|
24
|
+
return { payload: { isIncludeDeleted: isIncludeDeleted ?? false } };
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
updateProjectList(draft, action) {
|
|
28
|
+
draft.projectIds =
|
|
29
|
+
action.payload.data?.projects?.map((project) => project.zeni_project_id) ?? [];
|
|
30
|
+
draft.fetchState = 'Completed';
|
|
31
|
+
draft.error = undefined;
|
|
32
|
+
},
|
|
33
|
+
updateProjectListFailure(draft, action) {
|
|
34
|
+
draft.fetchState = 'Error';
|
|
35
|
+
draft.error = action.payload;
|
|
36
|
+
},
|
|
37
|
+
clearProjectList(draft) {
|
|
38
|
+
Object.assign(draft, exports.initialState);
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
_a = projectList.actions, exports.fetchProjectList = _a.fetchProjectList, exports.updateProjectList = _a.updateProjectList, exports.updateProjectListFailure = _a.updateProjectListFailure, exports.clearProjectList = _a.clearProjectList;
|
|
43
|
+
exports.default = projectList.reducer;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SelectorView } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
2
|
+
import { ProjectState } from '../../entity/project/projectReducer';
|
|
3
|
+
import { Project } from '../../entity/project/projectState';
|
|
4
|
+
import { ProjectListState } from './projectListState';
|
|
5
|
+
export interface ProjectListSelectorView extends SelectorView {
|
|
6
|
+
projects: Project[];
|
|
7
|
+
}
|
|
8
|
+
export declare const getProjectList: (projectState: ProjectState, projectListState: ProjectListState) => ProjectListSelectorView;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProjectList = void 0;
|
|
4
|
+
const projectSelector_1 = require("../../entity/project/projectSelector");
|
|
5
|
+
const getProjectList = (projectState, projectListState) => {
|
|
6
|
+
return {
|
|
7
|
+
projects: (0, projectSelector_1.getProjectsByIds)(projectState, projectListState.projectIds),
|
|
8
|
+
fetchState: projectListState.fetchState,
|
|
9
|
+
error: projectListState.error,
|
|
10
|
+
version: 0,
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
exports.getProjectList = getProjectList;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { RootState } from '../../reducer';
|
|
4
|
+
import { setEntityRecommendationForLineIdsForCategorization } from '../../view/expenseAutomationView/reducers/transactionsViewReducer';
|
|
5
|
+
import { ZeniAPI } from '../../zeniAPI';
|
|
6
|
+
import { fetchEntityRecommendationsForCategorization, setCategoryClassRecommendationsForCategorizationFailure, updateRecommendationForEntity } from './recommendationReducer';
|
|
7
|
+
export type ActionType = ReturnType<typeof updateRecommendationForEntity> | ReturnType<typeof fetchEntityRecommendationsForCategorization> | ReturnType<typeof setCategoryClassRecommendationsForCategorizationFailure> | ReturnType<typeof setEntityRecommendationForLineIdsForCategorization>;
|
|
8
|
+
export declare const fetchEntityRecommendationsForCategorizationEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchEntityRecommendationsForCategorizationEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const tenantSelector_1 = require("../../entity/tenant/tenantSelector");
|
|
7
|
+
const transactionHelper_1 = require("../../entity/transaction/transactionHelper");
|
|
8
|
+
const responsePayload_1 = require("../../responsePayload");
|
|
9
|
+
const transactionsViewReducer_1 = require("../../view/expenseAutomationView/reducers/transactionsViewReducer");
|
|
10
|
+
const accountListSelector_1 = require("../accountList/accountListSelector");
|
|
11
|
+
const transactionDetailState_1 = require("../transactionDetail/transactionDetailState");
|
|
12
|
+
const recommendationHelper_1 = require("./recommendationHelper");
|
|
13
|
+
const recommendationReducer_1 = require("./recommendationReducer");
|
|
14
|
+
// Categorization-list-only recommendations fetch.
|
|
15
|
+
//
|
|
16
|
+
// Concurrency model: groupBy on (transactionId.id, sorted lineIds) → switchMap
|
|
17
|
+
// inside each group → mergeMap to flatten groups. This means:
|
|
18
|
+
// • Same target (same transaction + same lineIds-set) — newer fetch cancels
|
|
19
|
+
// the prior in-flight fetch. Avoids the same-line stale-response race.
|
|
20
|
+
// • Different targets — run fully in parallel. Avoids the silent
|
|
21
|
+
// "stuck spinner" cancellation that the global-switchMap epic suffers
|
|
22
|
+
// from when the user moves between rows or JE lines mid-flight.
|
|
23
|
+
//
|
|
24
|
+
// The transactionsViewReducer's per-line categoryClassRecommendationsFetchState
|
|
25
|
+
// flag is set to In-Progress when the action enters this epic (start arm in
|
|
26
|
+
// extraReducers), Completed via setEntityRecommendationForLineIdsForCategorization,
|
|
27
|
+
// or Error via setCategoryClassRecommendationsForCategorizationFailure.
|
|
28
|
+
const fetchEntityRecommendationsForCategorizationEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(recommendationReducer_1.fetchEntityRecommendationsForCategorization.match), (0, operators_1.groupBy)((action) => {
|
|
29
|
+
const { transactionId, lineIds } = action.payload.transactionDetails;
|
|
30
|
+
return `${transactionId.id}|${[...lineIds].sort().join('|')}`;
|
|
31
|
+
}), (0, operators_1.mergeMap)((group$) => group$.pipe((0, operators_1.switchMap)((action) => {
|
|
32
|
+
const { entity, amount, transactionDetails, isFetchCOT, selectedTab, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
33
|
+
const query = {
|
|
34
|
+
amount,
|
|
35
|
+
transaction_id: (0, transactionDetailState_1.getActualTransactionID)(transactionDetails.transactionId.id),
|
|
36
|
+
transaction_type: transactionDetails.transaction.type,
|
|
37
|
+
line_ids: transactionDetails.lineIds,
|
|
38
|
+
};
|
|
39
|
+
if (isFetchCOT === true) {
|
|
40
|
+
query.include_cot = true;
|
|
41
|
+
}
|
|
42
|
+
const entityQuery = {
|
|
43
|
+
entity_name: entity.name,
|
|
44
|
+
entity_type: entity.type,
|
|
45
|
+
};
|
|
46
|
+
const recommendationUrl = entity.qboId === entity.name // entity id null case
|
|
47
|
+
? `${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/recommendations?query=${encodeURIComponent(JSON.stringify(entityQuery))}`
|
|
48
|
+
: `${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/${toEntityTypeURL(entity.type)}/${entity.qboId}/recommendations?query=${encodeURIComponent(JSON.stringify(query))}`;
|
|
49
|
+
return zeniAPI
|
|
50
|
+
.getJSON(recommendationUrl)
|
|
51
|
+
.pipe((0, operators_1.mergeMap)((response) => {
|
|
52
|
+
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
53
|
+
const actions = [];
|
|
54
|
+
const { transactionId, transaction, lineIds } = transactionDetails;
|
|
55
|
+
const recommendationWithCOTByLineId = (0, recommendationHelper_1.getRecommendationByLineIdWithCOTFromRecommendationPayloadWithCOT)(response.data.recommendations, lineIds);
|
|
56
|
+
const recommendations = (0, recommendationHelper_1.getRecommendationFromRecommendationPayload)(response.data.recommendations);
|
|
57
|
+
const transactionWithCOT = isFetchCOT === true &&
|
|
58
|
+
recommendationWithCOTByLineId != null
|
|
59
|
+
? (0, transactionHelper_1.getTransactionWithCOTFromRecommendations)(transaction, recommendationWithCOTByLineId)
|
|
60
|
+
: (0, transactionHelper_1.getTransactionWithCOT)(transaction);
|
|
61
|
+
actions.push((0, recommendationReducer_1.updateRecommendationForEntity)({
|
|
62
|
+
entityId: entity.id,
|
|
63
|
+
entityType: entity.type,
|
|
64
|
+
recommendations,
|
|
65
|
+
}));
|
|
66
|
+
if (recommendationWithCOTByLineId != null) {
|
|
67
|
+
const uncategorizedIncomeExpense = (0, accountListSelector_1.getUncategorizedAccounts)(state$.value.accountState, state$.value.accountListState, 'accountList');
|
|
68
|
+
actions.push((0, transactionsViewReducer_1.setEntityRecommendationForLineIdsForCategorization)(selectedTab, transactionId, transactionWithCOT, lineIds, entity, amount, recommendationWithCOTByLineId, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled, (0, tenantSelector_1.getIsAccountingClassesEnabled)(state$.value)));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Successful HTTP but no per-line recommendations — still
|
|
72
|
+
// need to clear the In-Progress flag, otherwise the
|
|
73
|
+
// skeleton sticks. Treat as a "no recommendations" success
|
|
74
|
+
// by firing the failure action with a benign error so the
|
|
75
|
+
// line flag flips out of In-Progress.
|
|
76
|
+
actions.push((0, recommendationReducer_1.setCategoryClassRecommendationsForCategorizationFailure)(selectedTab, transactionId, lineIds, (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Recommendations response missing per-line data')));
|
|
77
|
+
}
|
|
78
|
+
return (0, rxjs_1.from)(actions);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
return (0, rxjs_1.of)((0, recommendationReducer_1.setCategoryClassRecommendationsForCategorizationFailure)(selectedTab, transactionDetails.transactionId, transactionDetails.lineIds, response.status));
|
|
82
|
+
}
|
|
83
|
+
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, recommendationReducer_1.setCategoryClassRecommendationsForCategorizationFailure)(selectedTab, transactionDetails.transactionId, transactionDetails.lineIds, (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch recommendations for categorization REST API call errored out' +
|
|
84
|
+
JSON.stringify(error))))));
|
|
85
|
+
}))));
|
|
86
|
+
exports.fetchEntityRecommendationsForCategorizationEpic = fetchEntityRecommendationsForCategorizationEpic;
|
|
87
|
+
const toEntityTypeURL = (entityType) => `${entityType}s`;
|
|
@@ -22,7 +22,27 @@ export declare const fetchEntityRecommendationsByTransactionId: import("@reduxjs
|
|
|
22
22
|
isTransactionCategorizationFlow: any;
|
|
23
23
|
isFetchCOT: any;
|
|
24
24
|
isUncategorizedExpenseCategoryEnabled: boolean | undefined;
|
|
25
|
-
}, "recommendation/fetchEntityRecommendationsByTransactionId", never, never>,
|
|
25
|
+
}, "recommendation/fetchEntityRecommendationsByTransactionId", never, never>, fetchEntityRecommendationsForCategorization: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[entity: Entity, amount: number, transactionDetails: {
|
|
26
|
+
lineIds: ID[];
|
|
27
|
+
transaction: SupportedTransaction;
|
|
28
|
+
transactionId: TransactionID;
|
|
29
|
+
}, selectedTab: "review" | "autoCategorized", isFetchCOT?: any, isUncategorizedExpenseCategoryEnabled?: boolean | undefined], {
|
|
30
|
+
entity: Entity;
|
|
31
|
+
amount: number;
|
|
32
|
+
transactionDetails: {
|
|
33
|
+
lineIds: ID[];
|
|
34
|
+
transaction: SupportedTransaction;
|
|
35
|
+
transactionId: TransactionID;
|
|
36
|
+
};
|
|
37
|
+
selectedTab: "review" | "autoCategorized";
|
|
38
|
+
isFetchCOT: any;
|
|
39
|
+
isUncategorizedExpenseCategoryEnabled: boolean | undefined;
|
|
40
|
+
}, "recommendation/fetchEntityRecommendationsForCategorization", never, never>, setCategoryClassRecommendationsForCategorizationFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionId: TransactionID, lineIds: string[], error: ZeniAPIStatus<Record<string, unknown>>], {
|
|
41
|
+
selectedTab: "review" | "autoCategorized";
|
|
42
|
+
transactionId: TransactionID;
|
|
43
|
+
lineIds: string[];
|
|
44
|
+
error: ZeniAPIStatus<Record<string, unknown>>;
|
|
45
|
+
}, "recommendation/setCategoryClassRecommendationsForCategorizationFailure", never, never>, fetchRecommendationByEntityName: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[entityName: string, entityType: EntityType], {
|
|
26
46
|
entityName: string;
|
|
27
47
|
entityType: EntityType;
|
|
28
48
|
}, "recommendation/fetchRecommendationByEntityName", never, never>, fetchRecommendationByEntityId: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[entityId: string, entityType: EntityType], {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.clearRecommendation = exports.indicateReadyToInitializeRecommendation = exports.updateRecommendationForEntityFailure = exports.updateRecommendationForEntity = exports.fetchRecommendationByEntityId = exports.fetchRecommendationByEntityName = exports.fetchEntityRecommendationsByTransactionId = exports.initialState = void 0;
|
|
4
|
+
exports.clearRecommendation = exports.indicateReadyToInitializeRecommendation = exports.updateRecommendationForEntityFailure = exports.updateRecommendationForEntity = exports.fetchRecommendationByEntityId = exports.fetchRecommendationByEntityName = exports.setCategoryClassRecommendationsForCategorizationFailure = exports.fetchEntityRecommendationsForCategorization = exports.fetchEntityRecommendationsByTransactionId = exports.initialState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const recommendationState_1 = require("./recommendationState");
|
|
7
7
|
exports.initialState = {
|
|
@@ -110,12 +110,63 @@ const recommendation = (0, toolkit_1.createSlice)({
|
|
|
110
110
|
};
|
|
111
111
|
},
|
|
112
112
|
},
|
|
113
|
+
// Categorization-list-only fetch action. Mirrors the
|
|
114
|
+
// fetchEntityRecommendationsByTransactionId payload but is observed by a
|
|
115
|
+
// separate epic (with groupBy + switchMap, keyed on
|
|
116
|
+
// transactionId+lineIds-set) so concurrent fetches for distinct targets do
|
|
117
|
+
// not cancel each other. Reducer hooks in transactionsViewReducer use this
|
|
118
|
+
// to drive the per-line categoryClassRecommendationsFetchState flag.
|
|
119
|
+
fetchEntityRecommendationsForCategorization: {
|
|
120
|
+
reducer(draft, action) {
|
|
121
|
+
const { entity } = action.payload;
|
|
122
|
+
const key = (0, recommendationState_1.getEntityRecommendationKey)(entity.type, entity.id);
|
|
123
|
+
const existingRecommendation = draft.recommendationByEntity[key];
|
|
124
|
+
if (existingRecommendation == null) {
|
|
125
|
+
draft.recommendationByEntity[key] = {
|
|
126
|
+
...recommendationState_1.initialEntityRecommendationState,
|
|
127
|
+
fetchState: 'In-Progress',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
prepare(entity, amount, transactionDetails, selectedTab, isFetchCOT = false, isUncategorizedExpenseCategoryEnabled) {
|
|
132
|
+
return {
|
|
133
|
+
payload: {
|
|
134
|
+
entity,
|
|
135
|
+
amount,
|
|
136
|
+
transactionDetails,
|
|
137
|
+
selectedTab,
|
|
138
|
+
isFetchCOT,
|
|
139
|
+
isUncategorizedExpenseCategoryEnabled,
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
setCategoryClassRecommendationsForCategorizationFailure: {
|
|
145
|
+
reducer(
|
|
146
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
147
|
+
_draft,
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
149
|
+
_action) {
|
|
150
|
+
// The transactionsViewReducer handles the per-line flag flip; this
|
|
151
|
+
// reducer slice has no recommendation cache to update for the failure.
|
|
152
|
+
},
|
|
153
|
+
prepare(selectedTab, transactionId, lineIds, error) {
|
|
154
|
+
return {
|
|
155
|
+
payload: {
|
|
156
|
+
selectedTab,
|
|
157
|
+
transactionId,
|
|
158
|
+
lineIds,
|
|
159
|
+
error,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
},
|
|
113
164
|
clearRecommendation(draft) {
|
|
114
165
|
Object.assign(draft, exports.initialState);
|
|
115
166
|
},
|
|
116
167
|
},
|
|
117
168
|
});
|
|
118
|
-
_a = recommendation.actions, exports.fetchEntityRecommendationsByTransactionId = _a.fetchEntityRecommendationsByTransactionId, exports.fetchRecommendationByEntityName = _a.fetchRecommendationByEntityName, exports.fetchRecommendationByEntityId = _a.fetchRecommendationByEntityId, exports.updateRecommendationForEntity = _a.updateRecommendationForEntity, exports.updateRecommendationForEntityFailure = _a.updateRecommendationForEntityFailure, exports.indicateReadyToInitializeRecommendation = _a.indicateReadyToInitializeRecommendation, exports.clearRecommendation = _a.clearRecommendation;
|
|
169
|
+
_a = recommendation.actions, exports.fetchEntityRecommendationsByTransactionId = _a.fetchEntityRecommendationsByTransactionId, exports.fetchEntityRecommendationsForCategorization = _a.fetchEntityRecommendationsForCategorization, exports.setCategoryClassRecommendationsForCategorizationFailure = _a.setCategoryClassRecommendationsForCategorizationFailure, exports.fetchRecommendationByEntityName = _a.fetchRecommendationByEntityName, exports.fetchRecommendationByEntityId = _a.fetchRecommendationByEntityId, exports.updateRecommendationForEntity = _a.updateRecommendationForEntity, exports.updateRecommendationForEntityFailure = _a.updateRecommendationForEntityFailure, exports.indicateReadyToInitializeRecommendation = _a.indicateReadyToInitializeRecommendation, exports.clearRecommendation = _a.clearRecommendation;
|
|
119
170
|
exports.default = recommendation.reducer;
|
|
120
171
|
const doUpdateRecommendationForEntity = (draft, entityId, entityType, payload) => {
|
|
121
172
|
const key = (0, recommendationState_1.getEntityRecommendationKey)(entityType, entityId);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RootState } from '../../reducer';
|
|
2
2
|
export declare const getReimbursementCardReport: (state: RootState) => {
|
|
3
|
-
reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
|
|
3
|
+
reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
|
|
4
4
|
reportTitle: string;
|
|
5
5
|
version: string | number | undefined;
|
|
6
6
|
fetchState: import("../..").FetchState;
|