@zeniai/client-epic-state 5.1.82 → 5.1.83-betaRD1

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 (129) hide show
  1. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +2 -0
  2. package/lib/entity/jeSchedules/jeSchedulesPayload.js +2 -0
  3. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +4 -0
  4. package/lib/entity/jeSchedules/jeSchedulesSelector.js +13 -2
  5. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +2 -0
  6. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  7. package/lib/entity/snackbar/snackbarTypes.js +29 -0
  8. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +2 -0
  9. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  10. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +2 -0
  11. package/lib/epic.d.ts +5 -1
  12. package/lib/epic.js +5 -1
  13. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +2 -0
  14. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +13 -2
  15. package/lib/esm/entity/snackbar/snackbarTypes.js +29 -0
  16. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  17. package/lib/esm/epic.js +5 -1
  18. package/lib/esm/index.js +11 -5
  19. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  20. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +26 -3
  21. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +21 -0
  22. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +110 -0
  23. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +73 -0
  24. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +22 -0
  25. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +140 -0
  26. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +157 -28
  27. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  28. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +70 -0
  29. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +159 -22
  30. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -6
  31. package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +24 -4
  32. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +24 -4
  33. package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  34. package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +33 -9
  35. package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +35 -9
  36. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  37. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +32 -5
  38. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +23 -3
  39. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +24 -4
  40. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +24 -4
  41. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +20 -3
  42. package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +60 -17
  43. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  44. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  45. package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +29 -10
  46. package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +28 -5
  47. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +24 -4
  48. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +22 -14
  49. package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +46 -7
  50. package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +26 -8
  51. package/lib/esm/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  52. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  53. package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +41 -9
  54. package/lib/index.d.ts +15 -10
  55. package/lib/index.js +71 -50
  56. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  57. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.d.ts +2 -2
  58. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +24 -1
  59. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  60. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  61. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +45 -0
  62. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +114 -0
  63. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  64. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +77 -0
  65. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +6 -0
  66. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +26 -0
  67. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +36 -0
  68. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +145 -0
  69. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  70. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +7 -1
  71. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +44 -10
  72. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +158 -28
  73. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +25 -0
  74. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  75. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +34 -8
  76. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +10 -0
  77. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +75 -0
  78. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +4 -1
  79. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +161 -21
  80. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +58 -8
  81. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -8
  82. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.d.ts +2 -1
  83. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +23 -3
  84. package/lib/view/invoicing/createInvoice/createInvoiceEpic.d.ts +2 -1
  85. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +23 -3
  86. package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +22 -8
  87. package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
  88. package/lib/view/invoicing/discountAction/discountActionEpic.d.ts +2 -1
  89. package/lib/view/invoicing/discountAction/discountActionEpic.js +32 -8
  90. package/lib/view/invoicing/dunningAction/dunningActionEpic.d.ts +2 -1
  91. package/lib/view/invoicing/dunningAction/dunningActionEpic.js +34 -8
  92. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.d.ts +3 -1
  93. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
  94. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.d.ts +2 -1
  95. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +31 -4
  96. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.d.ts +2 -1
  97. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +22 -2
  98. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.d.ts +2 -1
  99. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +23 -3
  100. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.d.ts +2 -1
  101. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +23 -3
  102. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.d.ts +2 -1
  103. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/syncInvoicingSubscriptionCouponsEpic.js +19 -2
  104. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.d.ts +2 -1
  105. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +59 -16
  106. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewPayload.d.ts +13 -0
  107. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.d.ts +1 -1
  108. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +30 -0
  109. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.d.ts +11 -31
  110. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +4 -29
  111. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +15 -0
  112. package/lib/view/invoicing/invoicingQboView/epics/invoicingQboViewActionType.d.ts +2 -1
  113. package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +28 -9
  114. package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +27 -4
  115. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.d.ts +2 -1
  116. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +23 -3
  117. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.d.ts +24 -7
  118. package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +23 -16
  119. package/lib/view/invoicing/recordPayment/recordPaymentEpic.d.ts +2 -1
  120. package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +45 -6
  121. package/lib/view/invoicing/settingsView/settingsViewEpics.d.ts +2 -1
  122. package/lib/view/invoicing/settingsView/settingsViewEpics.js +25 -7
  123. package/lib/view/invoicing/settingsView/settingsViewReducer.d.ts +10 -1
  124. package/lib/view/invoicing/settingsView/settingsViewReducer.js +1 -1
  125. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +4 -2
  126. package/lib/view/invoicing/settingsView/settingsViewSelector.js +4 -1
  127. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.d.ts +2 -1
  128. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +40 -8
  129. package/package.json +1 -1
@@ -0,0 +1,73 @@
1
+ import { EMPTY, from, merge, of } from 'rxjs';
2
+ import { catchError, debounceTime, filter, mergeMap, switchMap, } from 'rxjs/operators';
3
+ import { getJEScheduleTransactionKey } from '../../../../../entity/jeSchedules/jeSchedulesTypes';
4
+ import { toTransactionType } from '../../../../../entity/transaction/stateTypes/transactionType';
5
+ import { updateScheduleTransactions } from '../../../../../entity/transaction/transactionReducer';
6
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
+ import { searchTransactionsForNewSchedule, searchTransactionsForNewScheduleFailure, searchTransactionsForNewScheduleSuccess, } from '../../../reducers/jeSchedulesViewReducer';
8
+ import { MIN_NEW_SCHEDULE_SEARCH_LENGTH } from '../../../types/jeSchedulesViewState';
9
+ /** Dropdown-sized result set — no pagination for Base Transaction search. */
10
+ const NEW_SCHEDULE_SEARCH_PAGE_SIZE = 10;
11
+ /** Fallback when the backend sends a null currency for a search result. */
12
+ const DEFAULT_CURRENCY_CODE = 'USD';
13
+ const DEFAULT_CURRENCY_SYMBOL = '$';
14
+ export const searchTransactionsForNewScheduleEpic = (actions$, _state$, zeniAPI) => {
15
+ const searchActions$ = actions$.pipe(filter(searchTransactionsForNewSchedule.match));
16
+ /** No API for empty or 1-char queries; immediate merge so switchMap cancels any in-flight HTTP. */
17
+ const newSearchTooShortOrClear$ = searchActions$.pipe(filter((action) => action.payload.query.trim().length < MIN_NEW_SCHEDULE_SEARCH_LENGTH));
18
+ const newSearchDebounced$ = searchActions$.pipe(filter((action) => action.payload.query.trim().length >= MIN_NEW_SCHEDULE_SEARCH_LENGTH), debounceTime(300));
19
+ return merge(newSearchTooShortOrClear$, newSearchDebounced$).pipe(switchMap((action) => {
20
+ const query = action.payload.query.trim();
21
+ if (query.length < MIN_NEW_SCHEDULE_SEARCH_LENGTH) {
22
+ return EMPTY;
23
+ }
24
+ const queryParam = {
25
+ page_size: NEW_SCHEDULE_SEARCH_PAGE_SIZE,
26
+ search_text: query,
27
+ je_schedule_type: action.payload.scheduleType,
28
+ };
29
+ return zeniAPI
30
+ .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/schedules/base_transaction_search?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
31
+ .pipe(mergeMap((response) => {
32
+ if (isSuccessResponse(response) && response.data != null) {
33
+ const { transactions } = response.data;
34
+ const transactionsPerCurrency = {};
35
+ transactions.forEach((transaction) => {
36
+ const { currency_code, currency_symbol } = transaction;
37
+ const currencyCode = currency_code ?? DEFAULT_CURRENCY_CODE;
38
+ const existing = transactionsPerCurrency[currencyCode];
39
+ transactionsPerCurrency[currencyCode] =
40
+ existing != null
41
+ ? {
42
+ currencySymbol: existing.currencySymbol,
43
+ transactions: [...existing.transactions, transaction],
44
+ }
45
+ : {
46
+ currencySymbol: currency_code == null
47
+ ? DEFAULT_CURRENCY_SYMBOL
48
+ : currency_symbol,
49
+ transactions: [transaction],
50
+ };
51
+ });
52
+ const actionsOut = Object.keys(transactionsPerCurrency).map((currencyCode) => {
53
+ const perCurrency = transactionsPerCurrency[currencyCode];
54
+ return updateScheduleTransactions(perCurrency.transactions, currencyCode, perCurrency.currencySymbol, 'merge');
55
+ });
56
+ actionsOut.push(searchTransactionsForNewScheduleSuccess({
57
+ searchResults: transactions.map((transaction) => getJEScheduleTransactionKey({
58
+ id: transaction.transaction_id,
59
+ type: toTransactionType(transaction.transaction_type),
60
+ lineId: transaction.line_id,
61
+ })),
62
+ }));
63
+ return from(actionsOut);
64
+ }
65
+ return of(searchTransactionsForNewScheduleFailure({
66
+ status: response.status,
67
+ }));
68
+ }), catchError((error) => of(searchTransactionsForNewScheduleFailure({
69
+ status: createZeniAPIStatus('Unexpected Error', 'Search transactions for new schedule errored: ' +
70
+ JSON.stringify(error)),
71
+ }))));
72
+ }));
73
+ };
@@ -0,0 +1,22 @@
1
+ import { EMPTY, of } from 'rxjs';
2
+ import { filter, mergeMap } from 'rxjs/operators';
3
+ import { convertToPeriod, toAbsoluteDay, } from '../../../../commonStateTypes/timePeriod';
4
+ import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
5
+ import { fetchJeSchedulesPage, updateJESchedulesUIState, } from '../../reducers/jeSchedulesViewReducer';
6
+ export const switchJESchedulesTabEpic = (actions$, state$) => actions$.pipe(filter(updateJESchedulesUIState.match), filter((action) => action.payload.selectedPageTab != null), mergeMap(() => {
7
+ const state = state$.value;
8
+ const { fetchState, refreshStatus } = state.expenseAutomationJESchedulesViewState;
9
+ if (fetchState === 'In-Progress' ||
10
+ refreshStatus.fetchState === 'In-Progress') {
11
+ return EMPTY;
12
+ }
13
+ const currentTenant = getCurrentTenant(state);
14
+ const selectedPeriod = state.expenseAutomationViewState.selectedPeriodByTenantId[currentTenant.tenantId];
15
+ const period = convertToPeriod(selectedPeriod);
16
+ const timePeriodStart = toAbsoluteDay(period.start);
17
+ const timePeriodEnd = toAbsoluteDay(period.end);
18
+ if (timePeriodStart == null || timePeriodEnd == null) {
19
+ return EMPTY;
20
+ }
21
+ return of(fetchJeSchedulesPage({ start: timePeriodStart, end: timePeriodEnd }, true));
22
+ }));
@@ -0,0 +1,140 @@
1
+ import { toAmount } from '../../../commonStateTypes/amount';
2
+ import { DEFAULT_DATE_FORMAT } from '../../../commonStateTypes/fiscalYearHelpers/formatZeniDateFY';
3
+ import { MONTH_YEAR_FORMAT } from '../../../commonStateTypes/fiscalYearHelpers/formatZeniDateFY';
4
+ import { LAST_SCHEDULE_DAY_OF_MONTH } from '../../../commonStateTypes/timePeriod';
5
+ import { getPostingDateAndStatusForIndex } from '../../scheduleView/scheduleDetailView/scheduleDetailLocalDataHelper';
6
+ import { mapScheduleTransactionToBaseScheduleTransactionPayload, } from '../../scheduleView/scheduleDetailView/scheduleDetailPayload';
7
+ const getNewScheduleMemo = (vendorName, schedulePostingDate, currentPeriod, totalPeriod, assetId) => {
8
+ const addAsset = assetId != null && assetId !== '' ? ` - ${assetId}` : '';
9
+ return `${vendorName} - ${schedulePostingDate.format(MONTH_YEAR_FORMAT)} (${currentPeriod} of ${totalPeriod})${addAsset}`;
10
+ };
11
+ /**
12
+ * Computes the month-by-month JE schedule breakdown for a brand-new schedule
13
+ * (no linked transaction yet) — replicates createNewSchedulesHelper's math
14
+ * (scheduleDetailLocalDataHelper.ts) exactly: lump-sum total split evenly
15
+ * across months with the rounding remainder absorbed by the last month, and a
16
+ * running balance that decrements each month and is forced to exactly 0 on
17
+ * the last row.
18
+ */
19
+ export const computeNewScheduleJeDetails = (localData, totalAmount, vendorName) => {
20
+ const period = localData.selectedMonths;
21
+ const startingMonth = localData.selectedDate;
22
+ if (startingMonth == null || period == null) {
23
+ return [];
24
+ }
25
+ const assetId = 'assetId' in localData ? localData.assetId : undefined;
26
+ const averageAmount = Math.abs(Math.round((totalAmount.amount / period) * 100) / 100);
27
+ const lastMonthAmount = Math.abs(Math.round((Math.abs(totalAmount.amount) - averageAmount * (period - 1)) * 100) / 100);
28
+ let runningBalance = Math.abs(totalAmount.amount);
29
+ const negativeNumbers = totalAmount.amount < 0 || runningBalance < 0;
30
+ const newJeDetails = [];
31
+ for (let index = 0; index < period; index++) {
32
+ if (runningBalance > averageAmount) {
33
+ runningBalance = Math.round((runningBalance - averageAmount) * 100) / 100;
34
+ }
35
+ else {
36
+ runningBalance = 0;
37
+ }
38
+ const amount = index === period - 1 ? lastMonthAmount : averageAmount;
39
+ runningBalance = index === period - 1 ? 0 : runningBalance;
40
+ const schedulePostingDate = startingMonth.add(index, 'month');
41
+ const { postingDate, postingStatus } = getPostingDateAndStatusForIndex(schedulePostingDate.month(), schedulePostingDate.year(), localData.lastDayOfMonth === true
42
+ ? undefined
43
+ : localData.selectedDayOfMonth);
44
+ newJeDetails.push({
45
+ postingDate,
46
+ amount: toAmount(negativeNumbers ? -amount : amount, totalAmount.currencyCode, totalAmount.currencySymbol),
47
+ runningBalance: toAmount(negativeNumbers ? -runningBalance : runningBalance, totalAmount.currencyCode, totalAmount.currencySymbol),
48
+ postingStatus,
49
+ memo: getNewScheduleMemo(vendorName, schedulePostingDate, index + 1, period, assetId),
50
+ jeLink: { type: 'unknown' },
51
+ });
52
+ }
53
+ return newJeDetails;
54
+ };
55
+ const mapNewJeDetailsToScheduledJournalEntryPayload = (jeScheduleDetails) => jeScheduleDetails.map((journalEntry) => ({
56
+ status: {
57
+ code: journalEntry.postingStatus,
58
+ label: journalEntry.postingStatus,
59
+ },
60
+ transaction_memo: journalEntry.memo,
61
+ third_party_id: journalEntry.jeLink.thirdPartyTransactionId ?? null,
62
+ expected_post_date: journalEntry.postingDate.format(DEFAULT_DATE_FORMAT),
63
+ amount: journalEntry.amount.amount,
64
+ balance: journalEntry.runningBalance.amount,
65
+ // Brand-new schedule — there is no prior scheduled-journal-entry history
66
+ // to cross-reference (unlike the legacy edit flow's equivalent mapper).
67
+ scheduled_journal_entry_id: null,
68
+ actual_post_date: null,
69
+ is_platform_generated: null,
70
+ je_schedule_id: null,
71
+ update_time: null,
72
+ create_time: null,
73
+ }));
74
+ /**
75
+ * Builds a savable schedule payload directly from a Base Transaction search
76
+ * result and the New Schedule form's local data — bypassing the legacy
77
+ * getJEScheduledTransactionByJEScheduleTransactionKey selector entirely,
78
+ * since that selector throws unless the entity has already round-tripped
79
+ * through a real GET /1.0/schedules/:id. A brand-new schedule has no such
80
+ * history, so this reads only from data already in hand (the selected
81
+ * transaction/line plus what the user filled into the form).
82
+ */
83
+ export const prepareNewSchedulePayload = (transaction, localData, scheduleType) => {
84
+ if (transaction.thirdPartyTransactionId == null ||
85
+ transaction.thirdPartyTransactionId === '') {
86
+ return { ok: false, reason: 'missing_third_party_id' };
87
+ }
88
+ const scheduleTransaction = transaction;
89
+ const vendorId = localData.selectedVendor?.id ?? transaction.vendorId ?? '';
90
+ const vendorName = localData.selectedVendor?.name ?? transaction.vendorName ?? '';
91
+ if (vendorId === '' || vendorName === '') {
92
+ return { ok: false, reason: 'missing_vendor' };
93
+ }
94
+ const vendor = {
95
+ vendor_id: vendorId,
96
+ vendor_name: vendorName,
97
+ };
98
+ const jeScheduleDetails = computeNewScheduleJeDetails(localData, scheduleTransaction.amount, vendorName);
99
+ const postingDate = localData.selectedDayOfMonth ??
100
+ (localData.lastDayOfMonth === true ? LAST_SCHEDULE_DAY_OF_MONTH : null);
101
+ const firstJEScheduleDate = jeScheduleDetails.length > 0
102
+ ? jeScheduleDetails[0].postingDate.format(DEFAULT_DATE_FORMAT)
103
+ : null;
104
+ const lastJEScheduleDate = jeScheduleDetails.length > 0
105
+ ? jeScheduleDetails[jeScheduleDetails.length - 1].postingDate.format(DEFAULT_DATE_FORMAT)
106
+ : null;
107
+ const isFixedAssets = scheduleType === 'fixed_assets';
108
+ const assetId = 'assetId' in localData ? localData.assetId : undefined;
109
+ const selectedAccumulatedDepreciationCategory = 'selectedAccumulatedDepreciationCategory' in localData
110
+ ? localData.selectedAccumulatedDepreciationCategory
111
+ : undefined;
112
+ const status = { code: 'new', label: 'New' };
113
+ const jeSchedulePayload = {
114
+ status,
115
+ vendor,
116
+ currency_code: scheduleTransaction.currency.currencyCode,
117
+ currency_symbol: scheduleTransaction.currency.currencySymbol,
118
+ period: localData.selectedMonths ?? null,
119
+ je_schedule_type: scheduleType,
120
+ posting_date: postingDate,
121
+ balance: scheduleTransaction.amount.amount,
122
+ start_date: firstJEScheduleDate,
123
+ end_date: lastJEScheduleDate,
124
+ je_credit_accounting_class_id: scheduleTransaction.classBase?.classId ?? null,
125
+ je_credit_account_id: isFixedAssets
126
+ ? (selectedAccumulatedDepreciationCategory ?? null)
127
+ : scheduleTransaction.account.accountId,
128
+ je_debit_account_id: localData.selectedAccount ?? null,
129
+ je_debit_accounting_class_id: localData.selectedClass ?? null,
130
+ other_attributes: assetId != null ? { asset_id: assetId } : {},
131
+ base_transaction: mapScheduleTransactionToBaseScheduleTransactionPayload(scheduleTransaction),
132
+ };
133
+ return {
134
+ ok: true,
135
+ payload: {
136
+ je_schedules: [jeSchedulePayload],
137
+ scheduled_journal_entries: mapNewJeDetailsToScheduledJournalEntryPayload(jeScheduleDetails),
138
+ },
139
+ };
140
+ };
@@ -2,8 +2,14 @@ import { createSlice } from '@reduxjs/toolkit';
2
2
  import { geNestedAccountIDHierarchyForReport } from '../../../commonStateTypes/accountView/getNestedAccountIDHierarchyForReport';
3
3
  import { toMonthYearPeriodId, } from '../../../commonStateTypes/timePeriod';
4
4
  import { mapAccountBasePayloadToAccountBase, mapAccountMetadataPayloadToAccountMetadata, } from '../../../entity/account/accountPayload';
5
- import { getJEScheduleTransactionDetailKeyPayload, } from '../../../entity/jeSchedules/jeSchedulesPayload';
5
+ import { getJEScheduleKey, getJEScheduleTransactionDetailKeyPayload, } from '../../../entity/jeSchedules/jeSchedulesPayload';
6
6
  import { mapAccountTypeRecommendationPayloadToAccountRecommendationByType, } from '../../accountMappingView/accountTypeRecommendation/accountTypeRecommendationPayload';
7
+ import { MIN_NEW_SCHEDULE_SEARCH_LENGTH, getJESchedulePeriodTabKey, } from '../types/jeSchedulesViewState';
8
+ function removeKeyFromEveryTabSlot(keysByPeriodAndTab, keyToRemove) {
9
+ for (const periodTabKey of Object.keys(keysByPeriodAndTab)) {
10
+ keysByPeriodAndTab[periodTabKey] = keysByPeriodAndTab[periodTabKey].filter((jeScheduleKey) => jeScheduleKey !== keyToRemove);
11
+ }
12
+ }
7
13
  export const accountSettingsInitialState = {
8
14
  localData: {
9
15
  selectedPrepaidExpensesAccountIds: [],
@@ -35,16 +41,33 @@ export const accountSettingsInitialState = {
35
41
  accruedExpensesNestedAccountListHierarchy: [],
36
42
  accruedExpensesRecommendations: [],
37
43
  };
44
+ export const getBaseNewScheduleLocalData = (scheduleType) => ({
45
+ scheduleType,
46
+ jeScheduleDetails: [],
47
+ });
48
+ export const newScheduleInitialState = {
49
+ fixed_assets: getBaseNewScheduleLocalData('fixed_assets'),
50
+ prepaid_expenses: getBaseNewScheduleLocalData('prepaid_expenses'),
51
+ };
52
+ export const searchTransactionsInitialState = {
53
+ searchResults: [],
54
+ fetchState: 'Not-Started',
55
+ error: undefined,
56
+ };
38
57
  export const initialState = {
39
- jeScheduleTransactionKeysByPeriod: {},
40
- failedJeScheduleTransactionKeysByPeriod: {},
58
+ jeScheduleTransactionKeysByPeriodAndTab: {},
59
+ jeScheduleAccruedKeysByPeriodAndTab: {},
60
+ failedJeScheduleTransactionKeysByPeriodAndTab: {},
41
61
  postStatusById: {},
42
62
  ignoreStatusById: {},
43
63
  jeScheduleLocalDataById: {},
44
64
  uiState: {
45
- searchString: '',
65
+ createdGroupCollapsed: false,
66
+ pendingGroupCollapsed: false,
46
67
  scrollPosition: { scrollTop: 0, scrollLeft: undefined },
47
- selectedMainTab: 'pending_review',
68
+ searchString: '',
69
+ selectedJETypeFilter: null,
70
+ selectedPageTab: 'schedules',
48
71
  sortKey: 'transactionDate',
49
72
  sortOrder: 'descending',
50
73
  totalCount: 0,
@@ -55,6 +78,13 @@ export const initialState = {
55
78
  error: undefined,
56
79
  },
57
80
  accountSettings: accountSettingsInitialState,
81
+ newSchedule: {
82
+ newScheduleState: newScheduleInitialState,
83
+ saveStatus: { fetchState: 'Not-Started', error: undefined },
84
+ searchTransactions: searchTransactionsInitialState,
85
+ fetchState: 'Not-Started',
86
+ error: undefined,
87
+ },
58
88
  fetchState: 'Not-Started',
59
89
  error: undefined,
60
90
  hasValidState() {
@@ -99,9 +129,11 @@ const expenseAutomationJESchedulesView = createSlice({
99
129
  },
100
130
  },
101
131
  fetchJeSchedulesSuccess(draft, action) {
102
- const { jeSchedules, selectedPeriod, failedJeSchedules, refreshViewInBackground, } = action.payload;
132
+ const { jeSchedules, selectedPeriod, selectedPageTab, failedJeSchedules, accruedJeSchedules, refreshViewInBackground, } = action.payload;
133
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
103
134
  const jeScheduleTransactionKeys = jeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
104
135
  const failedJeScheduleTransactionKeys = failedJeSchedules.map((schedules) => getJEScheduleTransactionDetailKeyPayload(schedules.base_transaction));
136
+ const jeScheduleAccruedKeys = accruedJeSchedules.map((schedule) => getJEScheduleKey(schedule));
105
137
  if (refreshViewInBackground === true &&
106
138
  draft.refreshStatus.fetchState === 'In-Progress') {
107
139
  draft.refreshStatus = { fetchState: 'Completed', error: undefined };
@@ -110,19 +142,25 @@ const expenseAutomationJESchedulesView = createSlice({
110
142
  draft.fetchState = 'Completed';
111
143
  draft.error = undefined;
112
144
  }
113
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleTransactionKeys;
114
- draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = failedJeScheduleTransactionKeys;
145
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
146
+ jeScheduleTransactionKeys;
147
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] =
148
+ jeScheduleAccruedKeys;
149
+ draft.failedJeScheduleTransactionKeysByPeriodAndTab[periodTabKey] =
150
+ failedJeScheduleTransactionKeys;
115
151
  },
116
152
  fetchJeSchedulesFailure(draft, action) {
117
- const { status, selectedPeriod } = action.payload;
153
+ const { status, selectedPeriod, selectedPageTab } = action.payload;
154
+ const periodTabKey = getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod));
118
155
  if (draft.refreshStatus.fetchState === 'In-Progress') {
119
156
  draft.refreshStatus = { fetchState: 'Error', error: status };
120
157
  }
121
158
  else {
122
159
  draft.fetchState = 'Error';
123
160
  draft.error = status;
161
+ draft.jeScheduleTransactionKeysByPeriodAndTab[periodTabKey] = [];
162
+ draft.jeScheduleAccruedKeysByPeriodAndTab[periodTabKey] = [];
124
163
  }
125
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = [];
126
164
  },
127
165
  retryJeSchedule(draft, action) {
128
166
  const { scheduledJournalEntryID } = action.payload;
@@ -210,17 +248,18 @@ const expenseAutomationJESchedulesView = createSlice({
210
248
  };
211
249
  },
212
250
  updateJeScheduleTransactionKeys: {
213
- prepare(jeScheduleKeys, selectedPeriod) {
251
+ prepare(jeScheduleKeys, selectedPeriod, selectedPageTab) {
214
252
  return {
215
253
  payload: {
216
254
  jeScheduleKeys: jeScheduleKeys,
217
255
  selectedPeriod: selectedPeriod,
256
+ selectedPageTab: selectedPageTab,
218
257
  },
219
258
  };
220
259
  },
221
260
  reducer(draft, action) {
222
- const { selectedPeriod, jeScheduleKeys } = action.payload;
223
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = jeScheduleKeys;
261
+ const { selectedPeriod, selectedPageTab, jeScheduleKeys } = action.payload;
262
+ draft.jeScheduleTransactionKeysByPeriodAndTab[getJESchedulePeriodTabKey(selectedPageTab, toMonthYearPeriodId(selectedPeriod))] = jeScheduleKeys;
224
263
  },
225
264
  },
226
265
  removeJeScheduleTransactionKey: {
@@ -233,12 +272,10 @@ const expenseAutomationJESchedulesView = createSlice({
233
272
  };
234
273
  },
235
274
  reducer(draft, action) {
236
- const { selectedPeriod, jeScheduleKey } = action.payload;
237
- const prevData = [
238
- ...(draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] ?? []),
239
- ];
240
- const filteredKeys = prevData.filter((jeKey) => jeKey !== jeScheduleKey);
241
- draft.jeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = filteredKeys;
275
+ const { jeScheduleKey } = action.payload;
276
+ // Dropped from every tab's slot, not just the visible one: once a schedule is ignored or
277
+ // resolved it must not reappear when the user switches tabs and hits a cached list.
278
+ removeKeyFromEveryTabSlot(draft.jeScheduleTransactionKeysByPeriodAndTab, jeScheduleKey);
242
279
  },
243
280
  },
244
281
  removeFailedJeScheduleTransactionKey: {
@@ -251,12 +288,8 @@ const expenseAutomationJESchedulesView = createSlice({
251
288
  };
252
289
  },
253
290
  reducer(draft, action) {
254
- const { selectedPeriod, failedJeScheduleKey } = action.payload;
255
- const prevData = [
256
- ...(draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] ?? []),
257
- ];
258
- const filteredKeys = prevData.filter((jeKey) => jeKey !== failedJeScheduleKey);
259
- draft.failedJeScheduleTransactionKeysByPeriod[toMonthYearPeriodId(selectedPeriod)] = filteredKeys;
291
+ const { failedJeScheduleKey } = action.payload;
292
+ removeKeyFromEveryTabSlot(draft.failedJeScheduleTransactionKeysByPeriodAndTab, failedJeScheduleKey);
260
293
  },
261
294
  },
262
295
  initializeJeScheduleLocalData: {
@@ -368,6 +401,91 @@ const expenseAutomationJESchedulesView = createSlice({
368
401
  clearJeAccountSettingsLocalData(draft) {
369
402
  draft.accountSettings.localData = accountSettingsInitialState.localData;
370
403
  },
404
+ initializeNewSchedule: {
405
+ prepare({ scheduleType, }) {
406
+ return { payload: { scheduleType } };
407
+ },
408
+ reducer() {
409
+ // Purely an epic-trigger action — the epic fans out the account/class
410
+ // list fetches plus resetNewScheduleLocalData.
411
+ },
412
+ },
413
+ resetNewScheduleLocalData: {
414
+ prepare({ scheduleType, }) {
415
+ return { payload: { scheduleType } };
416
+ },
417
+ reducer(draft, action) {
418
+ const { scheduleType } = action.payload;
419
+ draft.newSchedule.newScheduleState[scheduleType] =
420
+ getBaseNewScheduleLocalData(scheduleType);
421
+ },
422
+ },
423
+ updateNewScheduleLocalData(draft, action) {
424
+ const { scheduleType, localData } = action.payload;
425
+ draft.newSchedule.newScheduleState[scheduleType] = {
426
+ ...draft.newSchedule.newScheduleState[scheduleType],
427
+ ...localData,
428
+ };
429
+ },
430
+ searchTransactionsForNewSchedule: {
431
+ prepare({ query, scheduleType, }) {
432
+ return { payload: { query, scheduleType } };
433
+ },
434
+ reducer(draft, action) {
435
+ const trimmed = action.payload.query.trim();
436
+ // Cleared or too-short query: no API (see epic) — reset immediately.
437
+ if (trimmed.length < MIN_NEW_SCHEDULE_SEARCH_LENGTH) {
438
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
439
+ return;
440
+ }
441
+ draft.newSchedule.searchTransactions = {
442
+ ...draft.newSchedule.searchTransactions,
443
+ searchString: action.payload.query,
444
+ fetchState: 'In-Progress',
445
+ };
446
+ },
447
+ },
448
+ searchTransactionsForNewScheduleSuccess(draft, action) {
449
+ draft.newSchedule.searchTransactions = {
450
+ ...draft.newSchedule.searchTransactions,
451
+ searchResults: action.payload.searchResults,
452
+ fetchState: 'Completed',
453
+ error: undefined,
454
+ };
455
+ },
456
+ searchTransactionsForNewScheduleFailure(draft, action) {
457
+ draft.newSchedule.searchTransactions = {
458
+ ...draft.newSchedule.searchTransactions,
459
+ fetchState: 'Error',
460
+ error: action.payload.status,
461
+ };
462
+ },
463
+ clearSearchTransactionsForNewSchedule(draft) {
464
+ draft.newSchedule.searchTransactions = searchTransactionsInitialState;
465
+ },
466
+ saveNewSchedule: {
467
+ prepare({ scheduleType, }) {
468
+ return { payload: { scheduleType } };
469
+ },
470
+ reducer(draft) {
471
+ draft.newSchedule.saveStatus = {
472
+ fetchState: 'In-Progress',
473
+ error: undefined,
474
+ };
475
+ },
476
+ },
477
+ saveNewScheduleSuccess(draft) {
478
+ draft.newSchedule.saveStatus = {
479
+ fetchState: 'Completed',
480
+ error: undefined,
481
+ };
482
+ },
483
+ saveNewScheduleFailure(draft, action) {
484
+ draft.newSchedule.saveStatus = {
485
+ fetchState: 'Error',
486
+ error: action.payload.status,
487
+ };
488
+ },
371
489
  updateJESchedulesUIState(draft, action) {
372
490
  if (action.payload.sortKey != null) {
373
491
  draft.uiState.sortKey = action.payload.sortKey;
@@ -381,16 +499,27 @@ const expenseAutomationJESchedulesView = createSlice({
381
499
  if (action.payload.scrollPosition != null) {
382
500
  draft.uiState.scrollPosition = action.payload.scrollPosition;
383
501
  }
384
- if (action.payload.selectedMainTab != null) {
385
- draft.uiState.selectedMainTab = action.payload.selectedMainTab;
502
+ if (action.payload.selectedPageTab != null) {
503
+ draft.uiState.selectedPageTab = action.payload.selectedPageTab;
386
504
  }
387
505
  },
506
+ updateJEScheduleTypeFilter(draft, action) {
507
+ draft.uiState.selectedJETypeFilter = action.payload;
508
+ },
509
+ toggleJEPendingGroupCollapsed(draft) {
510
+ draft.uiState.pendingGroupCollapsed =
511
+ !draft.uiState.pendingGroupCollapsed;
512
+ },
513
+ toggleJECreatedGroupCollapsed(draft) {
514
+ draft.uiState.createdGroupCollapsed =
515
+ !draft.uiState.createdGroupCollapsed;
516
+ },
388
517
  clearExpenseAutomationJESchedulesView(draft) {
389
518
  Object.assign(draft, initialState);
390
519
  },
391
520
  },
392
521
  });
393
- export const { clearExpenseAutomationJESchedulesView, clearJeAccountSettingsLocalData, clearJeScheduleLocalData, fetchAccountSettingsListForAccountTypes, fetchJeSchedules, fetchJeSchedulesFailure, fetchJeSchedulesPage, fetchJeSchedulesSuccess, fetchRecommendationForAccountSettings, ignoreRecommendedJeSchedule, ignoreRecommendedJeScheduleFailure, ignoreRecommendedJeScheduleSuccess, initializeAccountSettingsView, initializeJeScheduleLocalData, removeFailedJeScheduleTransactionKey, removeJeScheduleLocalDataById, removeJeScheduleTransactionKey, retryJeSchedule, retryJeScheduleFailure, retryJeScheduleSuccess, saveAccountSettings, saveAccountSettingsFailure, saveAccountSettingsLocalData, saveAccountSettingsSuccess, updateAccountSettingsListForAccountTypes, updateAccountSettingsListForAccountTypesFailure, updateJESchedulesUIState, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, updateRecommendationForAccountSettings, updateRecommendationForAccountSettingsFailure, } = expenseAutomationJESchedulesView.actions;
522
+ export const { clearExpenseAutomationJESchedulesView, clearJeAccountSettingsLocalData, clearJeScheduleLocalData, clearSearchTransactionsForNewSchedule, fetchAccountSettingsListForAccountTypes, fetchJeSchedules, fetchJeSchedulesFailure, fetchJeSchedulesPage, fetchJeSchedulesSuccess, fetchRecommendationForAccountSettings, ignoreRecommendedJeSchedule, ignoreRecommendedJeScheduleFailure, ignoreRecommendedJeScheduleSuccess, initializeAccountSettingsView, initializeJeScheduleLocalData, initializeNewSchedule, removeFailedJeScheduleTransactionKey, removeJeScheduleLocalDataById, removeJeScheduleTransactionKey, resetNewScheduleLocalData, retryJeSchedule, retryJeScheduleFailure, retryJeScheduleSuccess, saveAccountSettings, saveAccountSettingsFailure, saveAccountSettingsLocalData, saveAccountSettingsSuccess, saveNewSchedule, saveNewScheduleFailure, saveNewScheduleSuccess, searchTransactionsForNewSchedule, searchTransactionsForNewScheduleFailure, searchTransactionsForNewScheduleSuccess, toggleJECreatedGroupCollapsed, toggleJEPendingGroupCollapsed, updateAccountSettingsListForAccountTypes, updateAccountSettingsListForAccountTypesFailure, updateJESchedulesUIState, updateJEScheduleTypeFilter, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, updateNewScheduleLocalData, updateRecommendationForAccountSettings, updateRecommendationForAccountSettingsFailure, } = expenseAutomationJESchedulesView.actions;
394
523
  export default expenseAutomationJESchedulesView.reducer;
395
524
  const doUpdateRecommendationForAccountSettings = (draft, payload) => {
396
525
  const { prepaidExpensesRecommendations, fixedAssetsRecommendations, accruedExpensesRecommendations, } = mapAccountTypeRecommendationPayloadToAccountRecommendationByType(payload);
@@ -0,0 +1,70 @@
1
+ import { getAccountIdsForTypes } from '../../../entity/account/accountSelector';
2
+ import { getScheduleTransactionById } from '../../../entity/transaction/transactionSelector';
3
+ import { getAccountIdsForLabel, getAccountList, getNestedAccountListHierarchy, } from '../../accountList/accountListSelector';
4
+ import { getClassList, getNestedClassListHierarchy, } from '../../classList/classListSelector';
5
+ import { getAccountsTypesForScheduleDetails } from '../../scheduleView/scheduleDetailView/scheduleDetailLocalDataHelper';
6
+ import { filterNestedAccountHierarchyById } from '../../scheduleView/scheduleDetailView/scheduleDetailSelector';
7
+ import { getAccountLabelForScheduleType, getAccountsTypesForScheduleEpics, } from '../../scheduleView/scheduleListView/scheduleListHelper';
8
+ /**
9
+ * The Base Transaction search is shared across schedule types (one search
10
+ * box, not one per prepaid_expenses/fixed_assets) — split out from
11
+ * getNewScheduleView so a consumer can read it without supplying an
12
+ * otherwise-irrelevant scheduleType.
13
+ */
14
+ export const getNewScheduleSearchTransactionsView = (state) => {
15
+ const { searchTransactions } = state.expenseAutomationJESchedulesViewState.newSchedule;
16
+ const searchTransactionsResults = searchTransactions.searchResults
17
+ .map((key) => getScheduleTransactionById(state.transactionState, key))
18
+ .filter((transaction) => transaction != null);
19
+ return {
20
+ searchTransactionsResults,
21
+ searchTransactionsFetchState: {
22
+ fetchState: searchTransactions.fetchState,
23
+ error: searchTransactions.error,
24
+ },
25
+ searchTransactionsString: searchTransactions.searchString,
26
+ };
27
+ };
28
+ export const getNewScheduleView = (state, scheduleType) => {
29
+ const { accountState, accountListState, classState, classListState } = state;
30
+ const { newSchedule } = state.expenseAutomationJESchedulesViewState;
31
+ const searchTransactionsView = getNewScheduleSearchTransactionsView(state);
32
+ const accountType = getAccountsTypesForScheduleEpics();
33
+ const newScheduleAccountTypes = getAccountsTypesForScheduleDetails(scheduleType);
34
+ const newScheduleAccountIds = getAccountIdsForTypes(accountState, newScheduleAccountTypes);
35
+ const allAccountList = getAccountList(accountState, accountListState, accountType.accountListKey);
36
+ const filteredAccounts = allAccountList.accounts.filter((account) => newScheduleAccountIds.includes(account.accountId));
37
+ const accountListNestedAccountHierarchy = filterNestedAccountHierarchyById(getNestedAccountListHierarchy(accountListState, accountType.accountListKey), filteredAccounts.map((account) => account.accountId));
38
+ const allClassList = getClassList(classState, classListState);
39
+ const classListNestedAccountHierarchy = getNestedClassListHierarchy(classListState);
40
+ let allDepreciationAccountList;
41
+ let allDepreciationAccountListNestedAccountHierarchy;
42
+ if (scheduleType === 'fixed_assets') {
43
+ const depreciationCategoryIds = getAccountIdsForTypes(accountState, [
44
+ 'fixed_assets',
45
+ 'other_assets',
46
+ ]);
47
+ const accountLabel = getAccountLabelForScheduleType('fixed_assets');
48
+ const fixedAssetLabelAccountIds = accountLabel != null
49
+ ? getAccountIdsForLabel(accountListState, accountType.accountListKey, accountLabel)
50
+ : [];
51
+ allDepreciationAccountList = allAccountList.accounts.filter((account) => depreciationCategoryIds.includes(account.accountId) &&
52
+ !fixedAssetLabelAccountIds.includes(account.accountId));
53
+ allDepreciationAccountListNestedAccountHierarchy =
54
+ filterNestedAccountHierarchyById(getNestedAccountListHierarchy(accountListState, accountType.accountListKey), allDepreciationAccountList.map((account) => account.accountId));
55
+ }
56
+ return {
57
+ scheduleType,
58
+ accountListNestedAccountHierarchy,
59
+ allAccountList: filteredAccounts,
60
+ allClassList: allClassList.classes,
61
+ allDepreciationAccountList,
62
+ allDepreciationAccountListNestedAccountHierarchy,
63
+ classListNestedAccountHierarchy,
64
+ newScheduleLocalData: newSchedule.newScheduleState[scheduleType],
65
+ saveStatus: newSchedule.saveStatus,
66
+ ...searchTransactionsView,
67
+ fetchState: newSchedule.fetchState,
68
+ error: newSchedule.error,
69
+ };
70
+ };