@zeniai/client-epic-state 4.20.1 → 4.20.2-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.
Files changed (128) hide show
  1. package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.d.ts +19 -0
  2. package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.js +2 -0
  3. package/lib/commonStateTypes/animations.d.ts +1 -1
  4. package/lib/entity/aiCfo/aiCfoSelector.d.ts +1 -2
  5. package/lib/entity/billPay/billTransaction/billTransactionState.d.ts +2 -2
  6. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +38 -0
  7. package/lib/entity/jeSchedules/jeSchedulesPayload.js +78 -0
  8. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +4 -1
  9. package/lib/entity/jeSchedules/jeSchedulesSelector.js +5 -1
  10. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +37 -0
  11. package/lib/entity/tenant/tenantPayload.d.ts +1 -0
  12. package/lib/entity/tenant/tenantReducer.js +1 -0
  13. package/lib/entity/tenant/tenantSelector.d.ts +1 -0
  14. package/lib/entity/tenant/tenantSelector.js +9 -1
  15. package/lib/entity/tenant/tenantState.d.ts +1 -0
  16. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +4 -1
  17. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
  18. package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +3 -0
  19. package/lib/entity/transaction/payloadTypes/transactionPayload.js +17 -1
  20. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +1 -0
  21. package/lib/entity/transaction/stateTypes/transaction.d.ts +5 -0
  22. package/lib/entity/transaction/stateTypes/transactionLine.d.ts +1 -1
  23. package/lib/epic.d.ts +2 -1
  24. package/lib/epic.js +2 -1
  25. package/lib/esm/common/aiCfo/aiCfoSuggestedQuestionsPageContext.js +1 -0
  26. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +78 -0
  27. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +5 -1
  28. package/lib/esm/entity/tenant/tenantReducer.js +1 -0
  29. package/lib/esm/entity/tenant/tenantSelector.js +7 -0
  30. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
  31. package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +17 -1
  32. package/lib/esm/epic.js +2 -1
  33. package/lib/esm/index.js +10 -8
  34. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +82 -1
  35. package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +8 -2
  36. package/lib/esm/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +29 -0
  37. package/lib/esm/view/classList/fetchClassListEpic.js +9 -2
  38. package/lib/esm/view/commonVendorView/vendorView/vendorViewSelector.js +18 -5
  39. package/lib/esm/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
  40. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +2 -2
  41. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +2 -2
  42. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +4 -3
  43. package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
  44. package/lib/esm/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
  45. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
  46. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +17 -1
  47. package/lib/esm/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
  48. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +63 -6
  49. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -4
  50. package/lib/esm/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
  51. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -6
  52. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +18 -1
  53. package/lib/esm/view/profitAndLossClassesView/horizontalSectionEmptyBalancesSlice.js +17 -0
  54. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -0
  55. package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +20 -29
  56. package/lib/esm/view/spendManagement/billPay/billList/billListSelector.js +10 -0
  57. package/lib/esm/view/spendManagement/billPay/billList/billListState.js +1 -0
  58. package/lib/esm/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
  59. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
  60. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
  61. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
  62. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
  63. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
  64. package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +7 -4
  65. package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
  66. package/lib/esm/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
  67. package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +2 -2
  68. package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
  69. package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
  70. package/lib/index.d.ts +15 -11
  71. package/lib/index.js +44 -32
  72. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  73. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +7 -0
  74. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +15 -1
  75. package/lib/view/aiCfoView/aiCfoViewReducer.js +83 -2
  76. package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +4 -1
  77. package/lib/view/aiCfoView/aiCfoViewSelector.js +9 -2
  78. package/lib/view/aiCfoView/aiCfoViewState.d.ts +15 -1
  79. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.d.ts +8 -0
  80. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +33 -0
  81. package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
  82. package/lib/view/classList/fetchClassListEpic.d.ts +1 -1
  83. package/lib/view/classList/fetchClassListEpic.js +8 -1
  84. package/lib/view/commonVendorView/vendorView/vendorViewSelector.d.ts +1 -0
  85. package/lib/view/commonVendorView/vendorView/vendorViewSelector.js +18 -5
  86. package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.d.ts +1 -0
  87. package/lib/view/commonVendorView/vendorsTabVendorView/vendorsTabVendorViewSelector.js +6 -2
  88. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +2 -2
  89. package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +1 -1
  90. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +4 -3
  91. package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
  92. package/lib/view/expenseAutomationView/helpers/saveTransactionHelper.js +2 -2
  93. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -2
  94. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +1 -1
  95. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +2 -2
  96. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +18 -2
  97. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +2 -0
  98. package/lib/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
  99. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +63 -6
  100. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +12 -4
  101. package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
  102. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +11 -5
  103. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +5 -0
  104. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +20 -0
  105. package/lib/view/profitAndLossClassesView/horizontalSectionEmptyBalancesSlice.d.ts +9 -0
  106. package/lib/view/profitAndLossClassesView/horizontalSectionEmptyBalancesSlice.js +20 -0
  107. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -0
  108. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +20 -29
  109. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  110. package/lib/view/spendManagement/billPay/billList/billListSelector.js +10 -0
  111. package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
  112. package/lib/view/spendManagement/billPay/billList/billListState.js +1 -0
  113. package/lib/view/spendManagement/billPay/billPayReview/billPayReviewSelector.js +7 -3
  114. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +5 -5
  115. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPayApproversDetailsEpic.js +7 -2
  116. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +13 -6
  117. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  118. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.js +1 -0
  119. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +2 -0
  120. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewSelector.js +6 -3
  121. package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.d.ts +1 -0
  122. package/lib/view/spendManagement/reimbursement/remiListView/remiListSelector.js +12 -0
  123. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
  124. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.js +1 -0
  125. package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +2 -2
  126. package/lib/view/transactionDetail/epics/saveTransactionHelper.js +2 -2
  127. package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +16 -14
  128. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import orderBy from 'lodash/orderBy';
2
+ import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
2
3
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
3
4
  import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
4
5
  import { getSupportedTransactionById, getSupportedTransactionsByIds, } from '../../../entity/transaction/transactionSelector';
@@ -7,7 +8,7 @@ import { getCompletedTransactionsCacheKey } from '../reducers/missingReceiptsVie
7
8
  import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
8
9
  import { isUnmatchedTabFileStatus, } from '../types/missingReceiptsViewState';
9
10
  export function getExpenseAutomationMissingReceiptsView(state) {
10
- const { expenseAutomationMissingReceiptsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, } = state;
11
+ const { expenseAutomationMissingReceiptsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
11
12
  const currentTenant = getCurrentTenant(state);
12
13
  const { selectedPeriodByTenantId } = expenseAutomationViewState;
13
14
  const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
@@ -36,7 +37,7 @@ export function getExpenseAutomationMissingReceiptsView(state) {
36
37
  transaction.lines.length > 0 &&
37
38
  transaction.lines[0]
38
39
  ?.class != null
39
- ? transaction.lines[0].class.className.toLowerCase()
40
+ ? transaction.lines[0].class?.className.toLowerCase()
40
41
  : null;
41
42
  case 'vendor':
42
43
  default:
@@ -175,9 +176,16 @@ export function getExpenseAutomationMissingReceiptsView(state) {
175
176
  vendorLogo: result.vendorLogo ?? transaction?.logo?.href,
176
177
  };
177
178
  });
179
+ const monthEndFetchState = monthYearPeriodId != null
180
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
181
+ : { fetchState: 'Not-Started', error: undefined };
182
+ const reducedFetchStatus = reduceAnyFetchState([
183
+ { fetchState, error },
184
+ monthEndFetchState,
185
+ ]);
178
186
  return {
179
- fetchState,
180
- error,
187
+ fetchState: reducedFetchStatus.fetchState,
188
+ error: reducedFetchStatus.error,
181
189
  uploadReceiptStatusById,
182
190
  uiState,
183
191
  refreshStatus,
@@ -13,7 +13,7 @@ import { getAccountList, getNestedAccountListHierarchy, } from '../../accountLis
13
13
  import { getClassList, getNestedClassListHierarchy, } from '../../classList/classListSelector';
14
14
  import { initialActionFetchState, initialReconciliationTabsState, initialState, } from '../reducers/reconciliationViewReducer';
15
15
  import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
16
- export const getExpenseAutomationReconciliationView = createSelector((state) => state, (state) => getCurrentTenant(state), (state) => state.expenseAutomationReconciliationViewState, (state) => state.expenseAutomationViewState, (state) => state.plaidAccountViewState, (state) => state.accountListState, (state) => state.accountState, (state) => state.classListState, (state) => state.classState, (state) => state.monthEndCloseChecksState, (state) => state.vendorState, (state, currentTenant, reconciliationViewState, expenseAutomationViewState, plaidAccountViewState, accountListState, accountState, classListState, classState, monthEndCloseChecksState, vendorState) => {
16
+ export const getExpenseAutomationReconciliationView = createSelector((state) => state, (state) => getCurrentTenant(state), (state) => state.expenseAutomationReconciliationViewState, (state) => state.expenseAutomationViewState, (state) => state.plaidAccountViewState, (state) => state.accountListState, (state) => state.accountState, (state) => state.classListState, (state) => state.classState, (state) => state.monthEndCloseChecksState, (state) => state.vendorState, (state) => state.monthEndCloseChecksViewState, (state, currentTenant, reconciliationViewState, expenseAutomationViewState, plaidAccountViewState, accountListState, accountState, classListState, classState, monthEndCloseChecksState, vendorState, monthEndCloseChecksViewState) => {
17
17
  const { selectedPeriodByTenantId } = expenseAutomationViewState;
18
18
  const reconcileTabUiState = reconciliationViewState.reconTabsState.reconcile.uiState;
19
19
  const reviewTabUiState = reconciliationViewState.reconTabsState.review.uiState;
@@ -35,6 +35,13 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
35
35
  }
36
36
  return acc;
37
37
  }, []);
38
+ const monthYearPeriodId = selectedPeriod != null ? toMonthYearPeriodId(selectedPeriod) : null;
39
+ const monthEndFetchState = monthYearPeriodId != null
40
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? {
41
+ fetchState: 'Not-Started',
42
+ error: undefined,
43
+ })
44
+ : { fetchState: 'Not-Started', error: undefined };
38
45
  if (accountReconForMonthYearPeriod == null) {
39
46
  return {
40
47
  bankAccounts: [],
@@ -44,10 +51,13 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
44
51
  classListNestedAccountHierarchy: [],
45
52
  allAccountList: [],
46
53
  allClassList: [],
47
- fetchStatus: {
48
- fetchState: reconciliationViewState.fetchState,
49
- error: reconciliationViewState.error,
50
- },
54
+ fetchStatus: reduceAnyFetchState([
55
+ {
56
+ fetchState: reconciliationViewState.fetchState,
57
+ error: reconciliationViewState.error,
58
+ },
59
+ monthEndFetchState,
60
+ ]),
51
61
  plaidConnectionDetails: plaidAccountViewState['expense_automation_reconcile']
52
62
  .plaidConnectionDetails,
53
63
  completionStatus: 'incomplete',
@@ -270,10 +280,13 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
270
280
  bankAccounts: uniqueBankAccounts,
271
281
  creditCards: uniqueCreditCards,
272
282
  accountReconciliationsByAccountID: reconList,
273
- fetchStatus: {
274
- fetchState: reconciliationViewState.fetchState,
275
- error: reconciliationViewState.error,
276
- },
283
+ fetchStatus: reduceAnyFetchState([
284
+ {
285
+ fetchState: reconciliationViewState.fetchState,
286
+ error: reconciliationViewState.error,
287
+ },
288
+ monthEndFetchState,
289
+ ]),
277
290
  plaidConnectionDetails: plaidAccountViewState['expense_automation_reconcile']
278
291
  .plaidConnectionDetails,
279
292
  reconciliationTabsState: reconciliationViewState.reconTabsState,
@@ -1,5 +1,5 @@
1
1
  import omit from 'lodash/omit';
2
- import { reduceAllFetchState } from '../../../commonStateTypes/reduceFetchState';
2
+ import { reduceAllFetchState, reduceAnyFetchState, } from '../../../commonStateTypes/reduceFetchState';
3
3
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
4
4
  import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
5
5
  import { getTransactionWithCOT } from '../../../entity/transaction/transactionHelper';
@@ -8,7 +8,7 @@ import { getAccountList, getNestedAccountListHierarchy, getUncategorizedAccounts
8
8
  import { getClassList, getNestedClassListHierarchy, } from '../../classList/classListSelector';
9
9
  import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
10
10
  export function getExpenseAutomationTransactionView(state) {
11
- const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, } = state;
11
+ const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
12
12
  const { selectedTransactionCategorizationTab } = expenseAutomationTransactionsViewState;
13
13
  const { uiState, refreshStatus, saveStatus, markAsNotMiscategorizedStatus, transactionIdsBySelectedPeriod, transactionReviewLocalDataById, selectedCheckBoxTransactionIds, transactionIdsWithUnsavedData, uploadReceiptStatusById, selectedTransactionId, selectedTransactionLineId, } = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab];
14
14
  const uncategorizedIncomeExpense = getUncategorizedAccounts(accountState, accountListState, 'accountList');
@@ -41,10 +41,16 @@ export function getExpenseAutomationTransactionView(state) {
41
41
  .filter((transaction) => transaction != null);
42
42
  const transactions = getSupportedTransactionsByIds(transactionState, transactionIds);
43
43
  const transactionsWithCOT = transactions.map((transaction) => getTransactionWithCOT(transaction));
44
- const fetchStatus = reduceAllFetchState([
45
- accountList,
46
- classList,
47
- expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab],
44
+ const monthEndFetchState = monthYearPeriodId != null
45
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
46
+ : { fetchState: 'Not-Started', error: undefined };
47
+ const fetchStatus = reduceAnyFetchState([
48
+ reduceAllFetchState([
49
+ accountList,
50
+ classList,
51
+ expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab],
52
+ ]),
53
+ monthEndFetchState,
48
54
  ]);
49
55
  const totalCountByReview = expenseAutomationTransactionsViewState.transactionCategorizationView.review
50
56
  .uiState.totalCount;
@@ -1 +1,18 @@
1
- export {};
1
+ import { stringToUnion } from '../../../commonStateTypes/stringToUnion';
2
+ const JE_SCHEDULE_SORT_KEYS = [
3
+ 'vendor',
4
+ 'category',
5
+ 'class',
6
+ 'depCategory',
7
+ 'scheduleCategory',
8
+ 'startMonth',
9
+ 'type',
10
+ 'amortizationPeriod',
11
+ 'jePostingDate',
12
+ 'remainingMonths',
13
+ 'runningBalance',
14
+ 'totalAmount',
15
+ 'transactionDate',
16
+ 'memo',
17
+ ];
18
+ export const toJEScheduleSortKey = (v) => stringToUnion(v, JE_SCHEDULE_SORT_KEYS);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Empty `COABalancesSlice` for horizontal P&L-by-class section / calculated headers when
3
+ * enrichment has not produced balances yet, or for UI mapping fallbacks.
4
+ * Structure matches {@link enrichProfitAndLossByClassHorizontalReport} output.
5
+ */
6
+ export function getEmptyHorizontalSectionBalancesSlice(firstMonthOfFY, timeframe = 'month') {
7
+ return {
8
+ balances: [],
9
+ additionalBalances: [],
10
+ filter: {
11
+ firstMonthOfFY,
12
+ timeframe,
13
+ balancesRange: { numberOfPeriods: 0, orderBy: 'ascending_date' },
14
+ additionalBalances: [],
15
+ },
16
+ };
17
+ }
@@ -3,6 +3,7 @@ import { getSummationFreeRangeTotalBalance } from '../../commonStateTypes/coaBal
3
3
  import { defaultCustomerCurrency } from '../../commonStateTypes/currencyHelper';
4
4
  import { reduceFetchStateParallelTimeframes } from '../../commonStateTypes/reduceFetchState';
5
5
  import { getSectionClassesViewReport } from '../../entity/sectionClassesViewV2/sectionClassesViewSelector';
6
+ import { HORIZONTAL_CLASS_TOTAL_BALANCE_ID, } from './profitAndLossClassesByClassHorizontalSelectorTypes';
6
7
  import { enrichProfitAndLossByClassHorizontalReport } from './profitAndLossHorizontalEnrichment';
7
8
  export const profitAndLossHorizontalIdsInOrder = [
8
9
  'income',
@@ -303,6 +304,7 @@ function buildHeaderBalances(classColumns, timeframe, selectedPeriod, currency)
303
304
  startDate,
304
305
  type: 'default',
305
306
  label: col.className,
307
+ id: col.classId,
306
308
  }));
307
309
  // Add a "Total" column
308
310
  balances.push({
@@ -312,6 +314,7 @@ function buildHeaderBalances(classColumns, timeframe, selectedPeriod, currency)
312
314
  startDate,
313
315
  type: 'default',
314
316
  label: 'Total',
317
+ id: HORIZONTAL_CLASS_TOTAL_BALANCE_ID,
315
318
  });
316
319
  return balances;
317
320
  }
@@ -1,4 +1,5 @@
1
1
  import { defaultCustomerCurrency } from '../../commonStateTypes/currencyHelper';
2
+ import { getEmptyHorizontalSectionBalancesSlice } from './horizontalSectionEmptyBalancesSlice';
2
3
  import { HORIZONTAL_CLASS_TOTAL_BALANCE_ID, } from './profitAndLossClassesByClassHorizontalSelectorTypes';
3
4
  /**
4
5
  * Populates `sectionHeaderBalancesSlice`, and per-account `accountReportData`, so the
@@ -39,17 +40,17 @@ function enrichHorizontalSection(report, section) {
39
40
  };
40
41
  const siblingsPerRow = buildSiblingIndicesPerRow(section.accounts, parentIndices);
41
42
  const hasChildFlags = computeHorizontalHasChildFlags(parentIndices);
42
- for (let i = 0; i < section.accounts.length; i++) {
43
- const row = section.accounts[i];
43
+ for (let accountIndex = 0; accountIndex < section.accounts.length; accountIndex++) {
44
+ const row = section.accounts[accountIndex];
44
45
  // Same column order as `report.classColumns` (see `pivotSectionToHorizontal`).
45
- const classRowAmounts = row.classBalances.map((b) => b.balance.amount);
46
+ const classRowAmounts = row.classBalances.map((classBalance) => classBalance.balance.amount);
46
47
  row.accountReportData = {
47
48
  accountId: row.accountId,
48
49
  accountName: row.accountName,
49
50
  accountType: row.accountType,
50
51
  depth: row.depth,
51
52
  balancesInTimeframe: buildHorizontalClassColumnBalancesSlice(report, classRowAmounts, row.rowTotal.amount),
52
- horizontalTreeView: buildHorizontalTreeViewFromPrecomputed(section.accounts, i, parentIndices, siblingsPerRow, hasChildFlags),
53
+ horizontalTreeView: buildHorizontalTreeViewFromPrecomputed(section.accounts, accountIndex, parentIndices, siblingsPerRow, hasChildFlags),
53
54
  };
54
55
  }
55
56
  }
@@ -67,23 +68,13 @@ function buildHorizontalClassColumnBalancesSlice(report, classAmounts, totalAmou
67
68
  const currencyCode = firstHeader?.balance.currencyCode ?? fallback.currencyCode;
68
69
  const currencySymbol = firstHeader?.balance.currencySymbol ?? fallback.currencySymbol;
69
70
  const timeframe = firstHeader?.balanceTimeFrame ?? 'month';
70
- const emptySlice = {
71
- balances: [],
72
- additionalBalances: [],
73
- filter: {
74
- firstMonthOfFY: report.firstMonthOfFY,
75
- timeframe,
76
- balancesRange: { numberOfPeriods: 0, orderBy: 'ascending_date' },
77
- additionalBalances: [],
78
- },
79
- };
80
71
  if (report.selectedPeriod == null) {
81
- return emptySlice;
72
+ return getEmptyHorizontalSectionBalancesSlice(report.firstMonthOfFY, timeframe);
82
73
  }
83
74
  const { startDate, endDate } = report.selectedPeriod;
84
- const balances = report.classColumns.map((col, i) => ({
75
+ const balances = report.classColumns.map((col, columnIndex) => ({
85
76
  balance: {
86
- amount: classAmounts[i] ?? 0,
77
+ amount: classAmounts[columnIndex] ?? 0,
87
78
  currencyCode,
88
79
  currencySymbol,
89
80
  },
@@ -134,22 +125,22 @@ function computeHorizontalAccountParentIndices(rows) {
134
125
  if (accountRow == null) {
135
126
  continue;
136
127
  }
137
- const d = accountRow.depth;
128
+ const depth = accountRow.depth;
138
129
  while (stack.length > 0) {
139
130
  const topRow = rows[stack[stack.length - 1]];
140
131
  if (topRow == null) {
141
132
  stack.pop();
142
133
  continue;
143
134
  }
144
- if (topRow.depth < d) {
135
+ if (topRow.depth < depth) {
145
136
  break;
146
137
  }
147
138
  stack.pop();
148
139
  }
149
- if (d > 2 && stack.length > 0) {
140
+ if (depth > 2 && stack.length > 0) {
150
141
  const peek = stack[stack.length - 1];
151
142
  const parentRow = rows[peek];
152
- if (parentRow != null && parentRow.depth === d - 1) {
143
+ if (parentRow != null && parentRow.depth === depth - 1) {
153
144
  parentIndex[rowIndex] = peek;
154
145
  }
155
146
  }
@@ -168,12 +159,12 @@ function buildSiblingIndicesPerRow(rows, parentIndices) {
168
159
  continue;
169
160
  }
170
161
  const key = `${parentRowIndex}:${accountRow.depth}`;
171
- let g = keyToIndices.get(key);
172
- if (g == null) {
173
- g = [];
174
- keyToIndices.set(key, g);
162
+ let siblingGroup = keyToIndices.get(key);
163
+ if (siblingGroup == null) {
164
+ siblingGroup = [];
165
+ keyToIndices.set(key, siblingGroup);
175
166
  }
176
- g.push(rowIndex);
167
+ siblingGroup.push(rowIndex);
177
168
  }
178
169
  const siblingsPerRow = new Array(accountRowCount);
179
170
  for (let rowIndex = 0; rowIndex < accountRowCount; rowIndex++) {
@@ -241,14 +232,14 @@ function buildHorizontalTreeViewFromPrecomputed(dfsOrderedAccountRows, currentRo
241
232
  const hasChildrenFlag = hasChildFlags[currentRowIndex];
242
233
  const treeDepth = accountRow != null ? Math.max(0, accountRow.depth - 2) : 0;
243
234
  const hasChildren = hasChildrenFlag === true;
244
- const sibs = siblingIndices ?? [currentRowIndex];
235
+ const siblings = siblingIndices ?? [currentRowIndex];
245
236
  return {
246
237
  subAccountAncestorMetadata: buildHorizontalSubAccountAncestorMetadataFromPrecomputed(dfsOrderedAccountRows, currentRowIndex, parentIndices, siblingsPerRow, hasChildFlags),
247
238
  treeDepth,
248
239
  hasChildren,
249
- hasSiblings: sibs.length > 1,
240
+ hasSiblings: siblings.length > 1,
250
241
  isLeaf: !hasChildren,
251
- isLastNode: currentRowIndex === sibs[sibs.length - 1],
242
+ isLastNode: currentRowIndex === siblings[siblings.length - 1],
252
243
  };
253
244
  }
254
245
  function buildHorizontalAccountChildIndicesByParent(parentIndices) {
@@ -416,6 +416,14 @@ export const getBillListOnSort = (sortKey, sortOrder, currentTab, transactions)
416
416
  transactionsWithNoSortKeyValue.push(transaction);
417
417
  }
418
418
  break;
419
+ case 'invoiceNumber':
420
+ if (transaction.documentId != null) {
421
+ transactionsWithSortKeyValue.push(transaction);
422
+ }
423
+ else {
424
+ transactionsWithNoSortKeyValue.push(transaction);
425
+ }
426
+ break;
419
427
  case 'dueDate':
420
428
  if (currentTab === 'draft') {
421
429
  if (Boolean(transaction.dueDate) === true) {
@@ -518,6 +526,8 @@ export const getBillListOnSort = (sortKey, sortOrder, currentTab, transactions)
518
526
  return transaction.totalAmountInUSD?.amount ?? 0;
519
527
  case 'paymentMethod':
520
528
  return transaction.billPayInfo.billPaymentMethodType.name;
529
+ case 'invoiceNumber':
530
+ return transaction.documentId;
521
531
  }
522
532
  }, getColumnWiseSortOrder(sortOrder));
523
533
  return [
@@ -43,6 +43,7 @@ const ALL_BILL_PAY_SORT_KEYS = [
43
43
  'invoiceDate',
44
44
  'name',
45
45
  'paymentMethod',
46
+ 'invoiceNumber',
46
47
  ];
47
48
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
48
49
  const toBillPaySortKeyType = (v) => stringToUnion(v, ALL_BILL_PAY_SORT_KEYS);
@@ -2,6 +2,7 @@ import recordGet from 'lodash/get';
2
2
  import { reduceFetchState } from '../../../../commonStateTypes/reduceFetchState';
3
3
  import { getContactsByIds } from '../../../../entity/billPay/contact/contactSelector';
4
4
  import { getPaymentAccountsByPaymentAccountIds } from '../../../../entity/paymentAccount/paymentAccountSelector';
5
+ import { getIsAccountingClassesEnabled } from '../../../../entity/tenant/tenantSelector';
5
6
  import { getVendorByVendorId } from '../../../../entity/vendor/vendorSelector';
6
7
  import { getAccountList } from '../../../accountList/accountListSelector';
7
8
  import { getAllFundingAccounts, } from '../../commonSetup/setupViewSelector';
@@ -73,11 +74,14 @@ export const getReviewPageBillDetail = (state, billId) => {
73
74
  }
74
75
  }
75
76
  if (sourceBillDetail != null) {
76
- sourceBillDetailFetchState = reduceFetchState([
77
+ const fetchStateList = [
77
78
  sourceBillDetail.fetchStatus,
78
79
  accountListState.byReportId['billPayAccountList'],
79
- classListState,
80
- ]).fetchState;
80
+ ];
81
+ if (getIsAccountingClassesEnabled(state)) {
82
+ fetchStateList.push(classListState);
83
+ }
84
+ sourceBillDetailFetchState = reduceFetchState(fetchStateList).fetchState;
81
85
  }
82
86
  }
83
87
  else {
@@ -3,6 +3,7 @@ import cloneDeep from 'lodash/cloneDeep';
3
3
  import { reduceAllFetchState, reduceAnyFetchState, } from '../../../../commonStateTypes/reduceFetchState';
4
4
  import { getApprovalRulesByIds } from '../../../../entity/approvalRule/approvalRuleSelector';
5
5
  import { getClassesByIds } from '../../../../entity/class/classSelector';
6
+ import { getIsAccountingClassesEnabled } from '../../../../entity/tenant/tenantSelector';
6
7
  import { getUserByUserId } from '../../../../entity/user/userSelector';
7
8
  import { getUserRoleByUserId } from '../../../../entity/userRole/userRoleSelector';
8
9
  export const getBillPaySetupApproverView = createSelector((state) => state.billPaySetupApproverViewState, (state) => state.approvalRuleState, (state) => state.userState, (billPaySetupApproverViewState, approvalRuleState, userState) => {
@@ -44,7 +45,7 @@ export const getBillPaySetupApproverView = createSelector((state) => state.billP
44
45
  newApprovalRuleId,
45
46
  };
46
47
  });
47
- export const getBillPaySetupApproverUpdateDataView = createSelector((state) => state.billPaySetupApproverViewState, (state) => state.approvalRuleState, (state) => state.userState, (state) => state.classState, (state) => state.classListState, (state) => state.userRoleState, (billPaySetupApproverViewState, approvalRuleState, userState, classState, classListState, userRoleState) => {
48
+ export const getBillPaySetupApproverUpdateDataView = createSelector((state) => state.billPaySetupApproverViewState, (state) => state.approvalRuleState, (state) => state.userState, (state) => state.classState, (state) => state.classListState, (state) => state.userRoleState, (state) => getIsAccountingClassesEnabled(state), (billPaySetupApproverViewState, approvalRuleState, userState, classState, classListState, userRoleState, isAccountingClassesEnabled) => {
48
49
  const { affectedEntityIds, approvalRuleIds, approverListState, billPaySetupApproverViewUpdateData, fetchState, error, listeningToPusherEvent, } = billPaySetupApproverViewState;
49
50
  const { approverIds, attributes } = approverListState;
50
51
  const allApprovalRules = getApprovalRulesByIds(approvalRuleState, approvalRuleIds);
@@ -92,10 +93,9 @@ export const getBillPaySetupApproverUpdateDataView = createSelector((state) => s
92
93
  allAttributes,
93
94
  filteredAttributes,
94
95
  billPaySetupApproverViewUpdateData,
95
- approverListFetchStatus: reduceAllFetchState([
96
- approverListState.fetchStatus,
97
- classListState,
98
- ]),
96
+ approverListFetchStatus: isAccountingClassesEnabled
97
+ ? reduceAllFetchState([approverListState.fetchStatus, classListState])
98
+ : approverListState.fetchStatus,
99
99
  fetchState,
100
100
  allAccountingClasses,
101
101
  error,
@@ -1,22 +1,27 @@
1
1
  import { concat, from } from 'rxjs';
2
2
  import { filter, mergeMap } from 'rxjs/operators';
3
+ import { getIsAccountingClassesEnabled } from '../../../../../entity/tenant/tenantSelector';
3
4
  import { fetchClassList } from '../../../../classList/classListReducer';
4
5
  import { fetchBillPayApproversDetails, fetchBillPayApproversList, } from '../billPaySetupApproverViewReducer';
5
6
  export const fetchBillPayApproversDetailsEpic = (actions$, state$) => actions$.pipe(filter(fetchBillPayApproversDetails.match), mergeMap((action) => {
6
7
  const { cacheOverride, includeUserRoles } = action.payload;
7
8
  const { billPaySetupApproverViewState, classListState } = state$.value;
8
9
  const { approverListState } = billPaySetupApproverViewState;
10
+ const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state$.value);
9
11
  const actions = [];
10
12
  if (cacheOverride === true) {
11
13
  actions.push(fetchBillPayApproversList(cacheOverride, includeUserRoles));
12
- actions.push(fetchClassList());
14
+ if (isAccountingClassesEnabled) {
15
+ actions.push(fetchClassList());
16
+ }
13
17
  }
14
18
  else {
15
19
  if (billPaySetupApproverViewState.hasValidState() === false &&
16
20
  approverListState.fetchStatus.fetchState !== 'In-Progress') {
17
21
  actions.push(fetchBillPayApproversList(true, includeUserRoles));
18
22
  }
19
- if (classListState.hasValidState() === false &&
23
+ if (isAccountingClassesEnabled &&
24
+ classListState.hasValidState() === false &&
20
25
  classListState.fetchState !== 'In-Progress') {
21
26
  actions.push(fetchClassList());
22
27
  }
@@ -7,6 +7,7 @@ import { getCompanyByCompanyId } from '../../../../entity/company/companySelecto
7
7
  import { getDepositAccountByDepositAccountId } from '../../../../entity/depositAccount/depositAccountSelector';
8
8
  import { getPaymentAccountByPaymentAccountId, getPaymentAccountsByPaymentAccountIds, } from '../../../../entity/paymentAccount/paymentAccountSelector';
9
9
  import { getPaymentInstrumentById, getPaymentInstrumentsByIds, } from '../../../../entity/paymentInstrument/paymentInstrumentSelector';
10
+ import { getIsAccountingClassesEnabled } from '../../../../entity/tenant/tenantSelector';
10
11
  import { getUserByUserId } from '../../../../entity/user/userSelector';
11
12
  import { getVendorByQboId, getVendorByVendorId, } from '../../../../entity/vendor/vendorSelector';
12
13
  import { dateNow } from '../../../../zeniDayJS';
@@ -172,12 +173,15 @@ export const getEditBillDetail = (state, isVendorRecommendationFeatureEnabled, i
172
173
  isCancelled = sourceBillDetail.billDetailLocalData.isCancelled;
173
174
  billStage = billPayInfo?.stage.code ?? 'draft';
174
175
  if (billViewState != null) {
175
- fetchState = reduceFetchState([
176
+ const fetchStateList = [
176
177
  sourceBillDetail.fetchStatus,
177
178
  accountListState.byReportId.billPayAccountList,
178
- classListState,
179
179
  billPaySetupApproverViewState,
180
- ]).fetchState;
180
+ ];
181
+ if (getIsAccountingClassesEnabled(state)) {
182
+ fetchStateList.push(classListState);
183
+ }
184
+ fetchState = reduceFetchState(fetchStateList).fetchState;
181
185
  deleteStatus = billViewState.deleteStatus;
182
186
  billActivities = getBillActivities(state, billId, billPayInfo?.stage.code);
183
187
  }
@@ -191,11 +195,14 @@ export const getEditBillDetail = (state, isVendorRecommendationFeatureEnabled, i
191
195
  }
192
196
  }
193
197
  else {
194
- fetchState = reduceFetchState([
198
+ const newBillFetchStateList = [
195
199
  accountListState.byReportId.billPayAccountList,
196
- classListState,
197
200
  billPaySetupApproverViewState,
198
- ]).fetchState;
201
+ ];
202
+ if (getIsAccountingClassesEnabled(state)) {
203
+ newBillFetchStateList.push(classListState);
204
+ }
205
+ fetchState = reduceFetchState(newBillFetchStateList).fetchState;
199
206
  }
200
207
  if (sourceBillDetail != null && fetchState == 'Completed') {
201
208
  const updatedRecord = sourceBillDetail.billDetailLocalData;
@@ -75,6 +75,7 @@ const ALL_CHARGE_CARD_SORT_KEYS = [
75
75
  'cardName',
76
76
  'department',
77
77
  'cardType',
78
+ 'accountType',
78
79
  'status',
79
80
  'utilisation',
80
81
  'limit',
@@ -219,6 +219,8 @@ const getCardsBySortKey = (card, sortKey) => {
219
219
  return card.cardName.toLowerCase();
220
220
  case 'cardType':
221
221
  return card.type.code;
222
+ case 'accountType':
223
+ return card.type.code.includes('credit') ? 'credit' : 'debit';
222
224
  case 'status':
223
225
  return card.status.code;
224
226
  case 'utilisation':
@@ -2,7 +2,7 @@ import recordGet from 'lodash/get';
2
2
  import { reduceFetchState } from '../../../../commonStateTypes/reduceFetchState';
3
3
  import { getBankAccountByBankAccountId } from '../../../../entity/bankAccount/bankAccountSelector';
4
4
  import { getAllCurrencies } from '../../../../entity/currency/currencySelector';
5
- import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
+ import { getCurrentTenant, getIsAccountingClassesEnabled, } from '../../../../entity/tenant/tenantSelector';
6
6
  import { getUserByUserId } from '../../../../entity/user/userSelector';
7
7
  import { getAccountList, getNestedAccountListHierarchy, } from '../../../accountList/accountListSelector';
8
8
  import { getBankAccount, } from '../../../bankAccountView/bankAccountViewSelector';
@@ -63,13 +63,16 @@ export const getEditRemiDetail = (state, reimbursementId) => {
63
63
  paymentTo: reimbursementInfo?.toAccount.billAccountId,
64
64
  };
65
65
  if (sourceRemiDetail != null) {
66
- fetchState = reduceFetchState([
66
+ const fetchStateList = [
67
67
  sourceRemiDetail.fetchStatus,
68
68
  accountListState.byReportId.reimbursementAccountList,
69
- classListState,
70
69
  merchantListState,
71
70
  reimbursementConfigState,
72
- ]).fetchState;
71
+ ];
72
+ if (getIsAccountingClassesEnabled(state)) {
73
+ fetchStateList.push(classListState);
74
+ }
75
+ fetchState = reduceFetchState(fetchStateList).fetchState;
73
76
  remiStage = reimbursementInfo?.stage.code ?? 'draft';
74
77
  createdBy = getUserByUserId(userState, reimbursement?.createdBy ?? '');
75
78
  createTime = reimbursement?.createTime;
@@ -45,6 +45,7 @@ export const getRemiList = (state, currentTimePeriod, isBulkActionFeatureEnabled
45
45
  return {
46
46
  ...reimbursement,
47
47
  submittedBy: getUserByUserId(userState, reimbursement.reimburseeUserId),
48
+ createdByUser: getUserByUserId(userState, reimbursement.createdBy),
48
49
  approvers: approvers,
49
50
  };
50
51
  });
@@ -415,6 +416,14 @@ export const getRemiListOnSort = (sortKey, sortOrder, currentTab, reimbursements
415
416
  reimbursementsWithNoSortKeyValue.push(reimbursement);
416
417
  }
417
418
  break;
419
+ case 'createdBy':
420
+ if (reimbursement.createdByUser != null) {
421
+ reimbursementsWithSortKeyValue.push(reimbursement);
422
+ }
423
+ else {
424
+ reimbursementsWithNoSortKeyValue.push(reimbursement);
425
+ }
426
+ break;
418
427
  }
419
428
  });
420
429
  const getColumnWiseSortOrder = (sortOrder) => {
@@ -422,6 +431,7 @@ export const getRemiListOnSort = (sortKey, sortOrder, currentTab, reimbursements
422
431
  case 'reportName':
423
432
  case 'type':
424
433
  case 'status':
434
+ case 'createdBy':
425
435
  return sortOrder === 'ascending' ? 'asc' : 'desc';
426
436
  default:
427
437
  return sortOrder === 'ascending' ? 'desc' : 'asc';
@@ -441,6 +451,8 @@ export const getRemiListOnSort = (sortKey, sortOrder, currentTab, reimbursements
441
451
  return getStatusPerTab(reimbursement);
442
452
  case 'amount':
443
453
  return reimbursement.amount.amount ?? 0;
454
+ case 'createdBy':
455
+ return `${reimbursement.createdByUser?.firstName ?? ''} ${reimbursement.createdByUser?.lastName ?? ''}`.toLowerCase();
444
456
  }
445
457
  }, getColumnWiseSortOrder(sortOrder));
446
458
  return [
@@ -55,6 +55,7 @@ export const toRemiSubTabUnderScoreType = (v) => stringToUnion(v, REMI_SUB_TAB_U
55
55
  const ALL_REIMBURSEMENT_SORT_KEYS = [
56
56
  'reportName',
57
57
  'submittedOn',
58
+ 'createdBy',
58
59
  'type',
59
60
  'status',
60
61
  'amount',
@@ -91,11 +91,11 @@ export const allTaskStatus = [
91
91
  },
92
92
  {
93
93
  code: 'done',
94
- name: 'Done',
94
+ name: 'In Review',
95
95
  },
96
96
  {
97
97
  code: 'resolved',
98
- name: 'Resolved',
98
+ name: 'Complete',
99
99
  },
100
100
  ];
101
101
  export const allTaskPriority = [
@@ -75,8 +75,8 @@ export const toTransactionUpdatesFromTransactionDetailLocalData = (transactionDe
75
75
  lineItem.account?.qboId !== accountLine.account.qboId &&
76
76
  Boolean(lineItem.account?.qboId);
77
77
  hasClassChanged =
78
- Boolean(lineItem.class?.qboId) &&
79
- lineItem.class?.qboId !== accountLine.class.qboId;
78
+ (lineItem.class?.qboId != null || accountLine.class?.qboId != null) &&
79
+ lineItem.class?.qboId !== accountLine.class?.qboId;
80
80
  const recommendedAccountBase = toRecommendedAccountBase(lineItem.amount.amount, lineItem.account);
81
81
  const recommendedClassBase = toRecommendedClassBase(lineItem.amount.amount, lineItem.class);
82
82
  const latestRecommendedCategory = lineItem.recommendedAccount;