@zeniai/client-epic-state 5.2.13 → 5.2.14-betaRD0

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 (126) hide show
  1. package/lib/entity/jeSchedules/jeScheduleHelper.d.ts +1 -0
  2. package/lib/entity/jeSchedules/jeScheduleHelper.js +7 -0
  3. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +78 -1
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.js +183 -4
  5. package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +4 -2
  6. package/lib/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  7. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +11 -2
  8. package/lib/entity/jeSchedules/jeSchedulesSelector.js +38 -3
  9. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +123 -1
  10. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +24 -1
  11. package/lib/entity/jeSchedules/jeSchedulesTypes.js +96 -1
  12. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  13. package/lib/entity/snackbar/snackbarTypes.js +3 -0
  14. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +2 -0
  15. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  16. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +2 -0
  17. package/lib/epic.d.ts +9 -1
  18. package/lib/epic.js +16 -0
  19. package/lib/esm/entity/jeSchedules/jeScheduleHelper.js +6 -0
  20. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +183 -5
  21. package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  22. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +36 -2
  23. package/lib/esm/entity/jeSchedules/jeSchedulesTypes.js +86 -0
  24. package/lib/esm/entity/snackbar/snackbarTypes.js +3 -0
  25. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  26. package/lib/esm/epic.js +16 -0
  27. package/lib/esm/index.js +17 -11
  28. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  29. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +9 -1
  30. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +41 -5
  31. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +45 -0
  32. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  33. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +104 -0
  34. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  35. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +138 -0
  36. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +79 -0
  37. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +180 -0
  38. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +111 -0
  39. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +28 -0
  40. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +140 -0
  41. package/lib/esm/view/expenseAutomationView/payload/jeSchedulesPayload.js +55 -0
  42. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +319 -29
  43. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  44. package/lib/esm/view/expenseAutomationView/selectors/jeAccountSettingsViewSelector.js +1 -0
  45. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +106 -0
  46. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +327 -22
  47. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -6
  48. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +24 -7
  49. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +1 -1
  50. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +8 -1
  51. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +42 -8
  52. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogSubFamilyEpics.js +8 -2
  53. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +19 -10
  54. package/lib/esm/view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector.js +2 -0
  55. package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +0 -1
  56. package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +15 -36
  57. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  58. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  59. package/lib/esm/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  60. package/lib/index.d.ts +24 -18
  61. package/lib/index.js +93 -48
  62. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  63. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +9 -1
  64. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.d.ts +3 -2
  65. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +39 -3
  66. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.d.ts +21 -0
  67. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +49 -0
  68. package/lib/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  69. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.d.ts +9 -0
  70. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +108 -0
  71. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  72. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +29 -0
  73. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +9 -0
  74. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +142 -0
  75. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  76. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +83 -0
  77. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.d.ts +13 -0
  78. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +187 -0
  79. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.d.ts +65 -0
  80. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +115 -0
  81. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +6 -0
  82. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +32 -0
  83. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +36 -0
  84. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +145 -0
  85. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  86. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +86 -3
  87. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.js +58 -1
  88. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +93 -12
  89. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +321 -29
  90. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -1
  91. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +2 -2
  92. package/lib/view/expenseAutomationView/selectorTypes/jeAccountSettingsViewSelectorTypes.d.ts +1 -0
  93. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +42 -0
  94. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  95. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +41 -7
  96. package/lib/view/expenseAutomationView/selectors/jeAccountSettingsViewSelector.js +1 -0
  97. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +21 -0
  98. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +112 -0
  99. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +34 -0
  100. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +335 -21
  101. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +1 -1
  102. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +83 -8
  103. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -8
  104. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +1 -1
  105. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.d.ts +13 -21
  106. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +24 -7
  107. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.d.ts +7 -0
  108. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +4 -3
  109. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.d.ts +18 -9
  110. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +9 -2
  111. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +15 -5
  112. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +43 -8
  113. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewState.d.ts +24 -0
  114. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogSubFamilyEpics.d.ts +1 -1
  115. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogSubFamilyEpics.js +8 -2
  116. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +18 -9
  117. package/lib/view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector.d.ts +6 -0
  118. package/lib/view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector.js +2 -0
  119. package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +0 -1
  120. package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.d.ts +13 -13
  121. package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +17 -38
  122. package/lib/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  123. package/lib/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  124. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.d.ts +4 -2
  125. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  126. package/package.json +1 -1
package/lib/epic.js CHANGED
@@ -198,9 +198,17 @@ const initializeAccountSettingsViewEpic_1 = require("./view/expenseAutomationVie
198
198
  const saveAccountSettingsViewEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/accountSettings/saveAccountSettingsViewEpic");
199
199
  const fetchJeSchedulePageEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic");
200
200
  const fetchJeSchedulesEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic");
201
+ const fetchOneTimeAccrualEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic");
201
202
  const ignoreRecommendedJeScheduleEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic");
202
203
  const initializeJeScheduleLocalDataEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/initializeJeScheduleLocalDataEpic");
204
+ const createOneTimeAccrualEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic");
205
+ const initializeNewScheduleEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic");
206
+ const saveNewScheduleEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic");
207
+ const searchTransactionsForNewScheduleEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic");
208
+ const oneTimeAccrualActionsEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic");
203
209
  const retryJeSchedulesEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/retryJeSchedulesEpic");
210
+ const revertJeScheduleEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic");
211
+ const switchJESchedulesTabEpic_1 = require("./view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic");
204
212
  const bulkUploadMatchResultToastEpic_1 = require("./view/expenseAutomationView/epics/missingReceipts/bulkUploadMatchResultToastEpic");
205
213
  const bulkUploadReceiptsEpic_1 = require("./view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic");
206
214
  const confirmBulkUploadMatchEpic_1 = require("./view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic");
@@ -786,6 +794,7 @@ const ALL_EPICS = [
786
794
  createNewSchedulesAccruedEpic_1.createNewSchedulesAccruedEpic,
787
795
  createNewSchedulesEpic_1.createNewSchedulesEpic,
788
796
  createNewTaskGroupEpic_1.createNewTaskGroupEpic,
797
+ createOneTimeAccrualEpic_1.createOneTimeAccrualEpic,
789
798
  createInternationalPaymentInstrumentEpic_1.createPaymentInstrumentEpic,
790
799
  createSessionAndSubmitEpic_1.createSessionAndSubmitEpic,
791
800
  createSessionEpic_1.createSessionEpic,
@@ -1065,6 +1074,7 @@ const ALL_EPICS = [
1065
1074
  fetchOnboardingCustomerSetupViewEpic_1.fetchOnboardingCustomerSetupViewEpic,
1066
1075
  fetchOnboardingCustomerViewEpic_1.fetchOnboardingCustomerViewEpic,
1067
1076
  fetchOnboardingViewEpic_1.fetchOnboardingViewEpic,
1077
+ fetchOneTimeAccrualEpic_1.fetchOneTimeAccrualEpic,
1068
1078
  fetchOpExByVendorReportEpic_1.fetchOpExByVendorEpic,
1069
1079
  fetchOpExByVendorReportForTimeframeEpic_1.fetchOpExByVendorReportForTimeframeEpic,
1070
1080
  fetchOpExByVendorReportSummaryEpic_1.fetchOpExByVendorReportSummaryEpic,
@@ -1219,6 +1229,7 @@ const ALL_EPICS = [
1219
1229
  initializeInvoicingCustomerAddressEpic_1.initializeInvoicingCustomerAddressEpic,
1220
1230
  initializeInvoicingSubscriptionAddressEpic_1.initializeInvoicingSubscriptionAddressEpic,
1221
1231
  initializeMyProfileLocalDataEpic_1.initializeMyProfileLocalDataEpic,
1232
+ initializeNewScheduleEpic_1.initializeNewScheduleEpic,
1222
1233
  initializeOnboardingCustomerViewUpdateDataEpic_1.initializeOnboardingCustomerViewUpdateDataEpic,
1223
1234
  initializeRemiSetupApproverViewUpdateDataEpic_1.initializeRemiSetupApproverViewUpdateDataEpic,
1224
1235
  initializeRemiToLocalStoreEpic_1.initializeRemiToLocalStoreEpic,
@@ -1241,6 +1252,7 @@ const ALL_EPICS = [
1241
1252
  markAsCompleteScheduleDetailEpic_1.markAsCompleteScheduleDetailEpic,
1242
1253
  markTransactionAsNotMiscategorizedEpic_2.markTransactionAsNotMiscategorizedEpic,
1243
1254
  notifyMeForFeatureEpic_1.notifyMeForFeatureEpic,
1255
+ oneTimeAccrualActionsEpic_1.oneTimeAccrualActionsEpic,
1244
1256
  parallelFetchAccountTransactionListEpic_1.parallelFetchAccountTransactionListEpic,
1245
1257
  parallelFetchClassTransactionListEpic_1.parallelFetchClassTransactionListEpic,
1246
1258
  parallelFetchEntityTransactionListEpic_1.parallelFetchEntityTransactionListEpic,
@@ -1284,6 +1296,7 @@ const ALL_EPICS = [
1284
1296
  retryJeSchedulesEpic_1.retryJeScheduleEpic,
1285
1297
  retryInvoicingQboSyncTaskEpic_1.retryInvoicingQboSyncTaskEpic,
1286
1298
  retryOrRefundBillEpic_1.retryOrRefundBillEpic,
1299
+ revertJeScheduleEpic_1.revertJeScheduleEpic,
1287
1300
  reviewDraftRemisBulkActionEpic_ts_1.reviewDraftRemisBulkActionEpic,
1288
1301
  reviewFluxAnalysisEpic_1.reviewFluxAnalysisViewEpic,
1289
1302
  revokeCardInviteEpic_1.revokeCardInviteEpic,
@@ -1319,6 +1332,7 @@ const ALL_EPICS = [
1319
1332
  saveInvoicingSubscriptionEpic_1.saveInvoicingSubscriptionEpic,
1320
1333
  saveMagicLinkBankAccountEpic_1.saveMagicLinkBankAccountEpic,
1321
1334
  saveNewAddressEpic_1.saveNewAddressEpic,
1335
+ saveNewScheduleEpic_1.saveNewScheduleEpic,
1322
1336
  saveNotificationPreferencesEpic_1.saveNotificationPreferencesEpic,
1323
1337
  saveNotificationSettingsEpic_1.saveNotificationSettingsEpic,
1324
1338
  saveOAuthConnectionEpic_1.saveOAuthConnectionEpic,
@@ -1343,6 +1357,7 @@ const ALL_EPICS = [
1343
1357
  saveVendorsTabVendorEpic_1.saveVendorsTabVendorEpic,
1344
1358
  scheduleTenantCreditScoreCronEpic_1.scheduleTenantCreditScoreCronEpic,
1345
1359
  searchTransactionsForManualMatchEpic_1.searchTransactionsForManualMatchEpic,
1360
+ searchTransactionsForNewScheduleEpic_1.searchTransactionsForNewScheduleEpic,
1346
1361
  seedAiCardCreationFormDraftEpic_1.seedAiCardCreationFormDraftEpic,
1347
1362
  seedAiCardPolicyFormDraftEpic_1.seedAiCardPolicyFormDraftEpic,
1348
1363
  sendCompanyMonthEndReportEpic_1.sendCompanyMonthEndReportEpic,
@@ -1366,6 +1381,7 @@ const ALL_EPICS = [
1366
1381
  invoicingBrandingFormEpics_1.submitInvoicingBrandingFormEpic,
1367
1382
  submitInvoicingQboSettingsEpic_1.submitInvoicingQboSettingsEpic,
1368
1383
  submitQuestionEpic_1.submitQuestionEpic,
1384
+ switchJESchedulesTabEpic_1.switchJESchedulesTabEpic,
1369
1385
  syncInvoicingSubscriptionCouponsEpic_1.syncInvoicingSubscriptionCouponsEpic,
1370
1386
  syncTabsAfterAutomatchEpic_1.syncTabsAfterAutomatchEpic,
1371
1387
  toggleReportUIOptionForecastModeEpic_1.toggleReportUIOptionForecastModeEpic,
@@ -1,3 +1,9 @@
1
1
  export function generateJEScheduleKey(jeScheduleId, jeScheduleType) {
2
2
  return `${jeScheduleId}_${jeScheduleType}`;
3
3
  }
4
+ // Suffixed rather than using the bare Mongo _id so the key is a distinct type from
5
+ // JEScheduleKey / JEScheduleTransactionKey and the three cannot be passed interchangeably.
6
+ // The unsuffixed id stays on the entity as `accrualId` for callers that need it.
7
+ export function generateJEOneTimeAccrualKey(accrualId) {
8
+ return `${accrualId}_one_time_accrual`;
9
+ }
@@ -1,9 +1,11 @@
1
1
  import { toAmount } from '../../commonStateTypes/amount';
2
2
  import { LAST_SCHEDULE_DAY_OF_MONTH, MAX_SCHEDULE_DAY_OF_MONTH, MIN_SCHEDULE_DAY_OF_MONTH, toScheduleDaysOfMonth, } from '../../commonStateTypes/timePeriod';
3
3
  import { date } from '../../zeniDayJS';
4
+ import { toZeniUrl } from '../../zeniUrl';
4
5
  import { toTransactionID, } from '../transaction/payloadTypes/transactionIDPayload';
5
6
  import { generateJEScheduleKey } from './jeScheduleHelper';
6
- import { getJEScheduleTransactionKey, toJournalEntryErrorCodeType, toScheduleJournalEntryStatusCodeType, toScheduleStatusCodeType, toScheduleTypesTypeStrict, } from './jeSchedulesTypes';
7
+ import { getJEScheduleTransactionKey, toJournalEntryErrorCodeType, toOneTimeAccrualAutomationTierType, toOneTimeAccrualOriginType, toOneTimeAccrualReversalPolicyType, toOneTimeAccrualReversalTriggerType, toOneTimeAccrualStatusCodeType, toScheduleJournalEntryStatusCodeType, toScheduleStatusCodeType, toScheduleTypesTypeStrict, } from './jeSchedulesTypes';
8
+ const USD_CURRENCY_CODE = 'USD';
7
9
  export function toScheduledJournalEntryState(payload, currency_code, currency_symbol) {
8
10
  return {
9
11
  status: {
@@ -202,6 +204,43 @@ function toJEScheduleAISummaries(payload) {
202
204
  : undefined,
203
205
  };
204
206
  }
207
+ if (payload.starting_month != null) {
208
+ result.startingMonth = {
209
+ confidence: payload.starting_month.confidence,
210
+ reasoning: payload.starting_month.reasoning,
211
+ cot: Array.isArray(payload.starting_month.cot)
212
+ ? payload.starting_month.cot
213
+ : undefined,
214
+ };
215
+ }
216
+ if (payload.end_date != null) {
217
+ result.endDate = {
218
+ confidence: payload.end_date.confidence,
219
+ reasoning: payload.end_date.reasoning,
220
+ cot: Array.isArray(payload.end_date.cot)
221
+ ? payload.end_date.cot
222
+ : undefined,
223
+ };
224
+ }
225
+ if (payload.posting_start_date != null) {
226
+ result.postingStartDate = {
227
+ confidence: payload.posting_start_date.confidence,
228
+ reasoning: payload.posting_start_date.reasoning,
229
+ cot: Array.isArray(payload.posting_start_date.cot)
230
+ ? payload.posting_start_date.cot
231
+ : undefined,
232
+ };
233
+ }
234
+ if (payload.schedule_summary != null) {
235
+ result.scheduleSummary = {
236
+ confidence: payload.schedule_summary.confidence,
237
+ reasoning: payload.schedule_summary.reasoning,
238
+ reasoningLong: payload.schedule_summary.reasoning_long,
239
+ cot: Array.isArray(payload.schedule_summary.cot)
240
+ ? payload.schedule_summary.cot
241
+ : undefined,
242
+ };
243
+ }
205
244
  return Object.keys(result).length > 0 ? result : undefined;
206
245
  }
207
246
  function toJEScheduleRecommendations(payload) {
@@ -248,9 +287,18 @@ export function toJEScheduledTransaction(payload) {
248
287
  startDate: payload.start_date != null ? date(payload.start_date) : undefined,
249
288
  endDate: payload.end_date != null ? date(payload.end_date) : undefined,
250
289
  period: payload.period != null ? Number(payload.period) : undefined,
290
+ recurringAmount: payload.recurring_amount != null
291
+ ? {
292
+ amount: payload.recurring_amount,
293
+ currencyCode: payload.currency_code,
294
+ currencySymbol: payload.currency_symbol,
295
+ }
296
+ : undefined,
297
+ postedCount: payload.posted_count ?? undefined,
251
298
  updatedByUserID: payload.updated_by.user_id,
252
299
  balanceAsOfToday: payload.balance ?? undefined,
253
300
  updatedAt: payload.updated_at != null ? date(payload.updated_at) : undefined,
301
+ createTime: payload.create_time != null ? date(payload.create_time) : undefined,
254
302
  jeCredit: {
255
303
  accountId: payload.je_credit_account_id ?? undefined,
256
304
  accountingClassId: payload.je_credit_accounting_class_id ?? undefined,
@@ -275,6 +323,7 @@ export function toJEScheduledTransaction(payload) {
275
323
  : {},
276
324
  scheduledJournalEntry: [],
277
325
  aiSummaries: toJEScheduleAISummaries(payload.ai_summaries),
326
+ confidenceScore: payload.confidence_score ?? undefined,
278
327
  createdByUserID: payload.created_by?.user_id ?? undefined,
279
328
  recommendations: toJEScheduleRecommendations(payload.recommendations),
280
329
  };
@@ -287,17 +336,20 @@ export function toJEAccruedScheduledTransaction(payload) {
287
336
  label: payload.status.label,
288
337
  },
289
338
  vendorId: payload.vendor.vendor_id,
339
+ // The accrued payload extends JEScheduledTransactionPayload, so it carries currency_code and
340
+ // currency_symbol like every other schedule -- this mapper was hardcoding USD over fields it
341
+ // already had.
290
342
  recurringAmount: {
291
343
  amount: payload.recurring_amount,
292
- currencyCode: 'USD',
293
- currencySymbol: '$',
344
+ currencyCode: payload.currency_code,
345
+ currencySymbol: payload.currency_symbol,
294
346
  },
295
347
  otherAttributes: {
296
348
  startingBalance: payload.other_attributes?.starting_balance != null
297
349
  ? {
298
350
  amount: payload.other_attributes?.starting_balance ?? 0,
299
- currencyCode: 'USD',
300
- currencySymbol: '$',
351
+ currencyCode: payload.currency_code,
352
+ currencySymbol: payload.currency_symbol,
301
353
  }
302
354
  : undefined,
303
355
  },
@@ -306,6 +358,9 @@ export function toJEAccruedScheduledTransaction(payload) {
306
358
  endDate: payload.end_date != null ? date(payload.end_date) : undefined,
307
359
  period: payload.period != null ? Number(payload.period) : undefined,
308
360
  updatedByUserID: payload.updated_by.user_id,
361
+ // The accrued joiner resolves createdByUserID into the "Created by" cell. Without this the
362
+ // payload's created_by was dropped here and every accrued row rendered a hyphen.
363
+ createdByUserID: payload.created_by?.user_id ?? undefined,
309
364
  balanceAsOfToday: payload.balance ?? undefined,
310
365
  updatedAt: payload.updated_at != null ? date(payload.updated_at) : undefined,
311
366
  jeCredit: {
@@ -332,3 +387,126 @@ export function toJEAccruedScheduledTransaction(payload) {
332
387
  jeScheduleType: toScheduleTypesTypeStrict(payload.je_schedule_type),
333
388
  };
334
389
  }
390
+ /**
391
+ * Reads the months in the order the snapshot gives them rather than deriving a range: a vendor that
392
+ * skipped a month has no entry for it, so filling gaps would invent history that was never billed.
393
+ */
394
+ function toJEOneTimeAccrualMonthlyTotals(snapshot, currencyCode) {
395
+ const monthlyTotals = snapshot.monthly_totals;
396
+ if (monthlyTotals == null) {
397
+ return [];
398
+ }
399
+ const months = snapshot.sorted_months ?? Object.keys(monthlyTotals).sort();
400
+ return months
401
+ .filter((month) => monthlyTotals[month] != null)
402
+ .map((month) => ({
403
+ month,
404
+ amount: toOneTimeAccrualAmount(monthlyTotals[month], currencyCode),
405
+ }));
406
+ }
407
+ function toJEOneTimeAccrualProfileSnapshot(payload, currencyCode) {
408
+ if (payload == null) {
409
+ return undefined;
410
+ }
411
+ const billingPattern = payload.billing_pattern;
412
+ return {
413
+ monthlyTotals: toJEOneTimeAccrualMonthlyTotals(payload, currencyCode),
414
+ billingPattern: billingPattern != null
415
+ ? {
416
+ frequency: billingPattern.frequency ?? undefined,
417
+ monthsOfHistory: billingPattern.months_of_history ?? undefined,
418
+ consistencyScore: billingPattern.consistency_score ?? undefined,
419
+ billingLagDays: billingPattern.billing_lag_days ?? undefined,
420
+ typicalBillDay: billingPattern.typical_bill_day ?? undefined,
421
+ avgAmount: billingPattern.avg_amount != null
422
+ ? toOneTimeAccrualAmount(billingPattern.avg_amount, currencyCode)
423
+ : undefined,
424
+ lastBillAmount: billingPattern.last_bill_amount != null
425
+ ? toOneTimeAccrualAmount(billingPattern.last_bill_amount, currencyCode)
426
+ : undefined,
427
+ lastBillDate: billingPattern.last_bill_date != null
428
+ ? date(billingPattern.last_bill_date)
429
+ : undefined,
430
+ }
431
+ : undefined,
432
+ };
433
+ }
434
+ function toJEOneTimeAccrualAiSuggestion(payload, currencyCode) {
435
+ if (payload == null) {
436
+ return undefined;
437
+ }
438
+ return {
439
+ memo: payload.memo ?? undefined,
440
+ jeDebitAccountName: payload.je_debit_account_name ?? undefined,
441
+ jeCreditAccountName: payload.je_credit_account_name ?? undefined,
442
+ estimatedAmount: payload.estimated_amount != null
443
+ ? toOneTimeAccrualAmount(payload.estimated_amount, currencyCode)
444
+ : undefined,
445
+ };
446
+ }
447
+ export function toJEOneTimeAccrual(payload) {
448
+ return {
449
+ accrualId: payload._id,
450
+ vendorId: payload.vendor_id,
451
+ vendorName: payload.vendor_name,
452
+ serviceMonth: payload.service_month,
453
+ accrualStatus: toOneTimeAccrualStatusCodeType(payload.status),
454
+ origin: toOneTimeAccrualOriginType(payload.origin),
455
+ automationTier: payload.automation_tier != null
456
+ ? toOneTimeAccrualAutomationTierType(payload.automation_tier)
457
+ : undefined,
458
+ estimatedAmount: toOneTimeAccrualAmount(payload.estimated_amount, payload.currency),
459
+ memo: payload.memo ?? '',
460
+ profileSnapshot: toJEOneTimeAccrualProfileSnapshot(payload.profile_snapshot, payload.currency),
461
+ isIgnored: payload.is_ignored === true,
462
+ aiSuggestion: toJEOneTimeAccrualAiSuggestion(payload.ai_suggestion, payload.currency),
463
+ // Exclusive by contract: a scheduled row reverses on expectedReversalDate and bills never
464
+ // drive it, so the two never need reconciling. Defaulting to on_bill_match matches the
465
+ // create path's default when the field is absent on an older document.
466
+ reversalPolicy: toOneTimeAccrualReversalPolicyType(payload.reversal_policy ?? 'on_bill_match'),
467
+ reversalTrigger: toOneTimeAccrualReversalTriggerType(payload.reversal_trigger ?? undefined),
468
+ expectedReversalDate: payload.expected_reversal_date != null
469
+ ? date(payload.expected_reversal_date)
470
+ : undefined,
471
+ postingDate: payload.posting_date != null ? date(payload.posting_date) : undefined,
472
+ actualPostDate: payload.actual_post_date != null
473
+ ? date(payload.actual_post_date)
474
+ : undefined,
475
+ actualReversalPostDate: payload.actual_reversal_post_date != null
476
+ ? date(payload.actual_reversal_post_date)
477
+ : undefined,
478
+ jeDebitAccountId: payload.je_debit_account_id ?? undefined,
479
+ jeDebitAccountName: payload.je_debit_account_name ?? undefined,
480
+ jeDebitAccountingClassId: payload.je_debit_accounting_class_id ?? undefined,
481
+ jeDebitAccountingClassName: payload.je_debit_accounting_class_name ?? undefined,
482
+ jeCreditAccountId: payload.je_credit_account_id ?? undefined,
483
+ jeCreditAccountName: payload.je_credit_account_name ?? undefined,
484
+ jeCreditAccountingClassId: payload.je_credit_accounting_class_id ?? undefined,
485
+ jeCreditAccountingClassName: payload.je_credit_accounting_class_name ?? undefined,
486
+ transactionId: payload.transaction_id ?? undefined,
487
+ transactionIntegrationId: payload.transaction_integration_id ?? undefined,
488
+ reversalTransactionId: payload.reversal_transaction_id ?? undefined,
489
+ createdBy: toJEOneTimeAccrualCreator(payload.created_by_user),
490
+ };
491
+ }
492
+ // The accrual wire format carries a currency CODE but no symbol, so the symbol has to be derived.
493
+ // Only USD has a known glyph today (the create path is USD-only); anything else falls back to the
494
+ // code, which reads correctly as "EUR 1,200" rather than silently rendering a wrong "$".
495
+ function toOneTimeAccrualAmount(amount, currencyCode) {
496
+ const code = currencyCode ?? USD_CURRENCY_CODE;
497
+ return toAmount(amount, code, code === USD_CURRENCY_CODE ? '$' : code);
498
+ }
499
+ function toJEOneTimeAccrualCreator(payload) {
500
+ if (payload == null) {
501
+ return undefined;
502
+ }
503
+ return {
504
+ userId: payload.user_id,
505
+ email: payload.email ?? undefined,
506
+ firstName: payload.first_name ?? undefined,
507
+ lastName: payload.last_name ?? undefined,
508
+ photo: payload.photo?.original != null
509
+ ? toZeniUrl(payload.photo.original)
510
+ : undefined,
511
+ };
512
+ }
@@ -1,10 +1,12 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
2
  import assignWith from 'lodash/assignWith';
3
3
  import { clearAll } from '../../rootActions';
4
- import { getJEScheduleKey, getJEScheduleTransactionDetailKeyPayload, toJEAccruedScheduledTransaction, toJEScheduledTransaction, toScheduledJournalEntryState, } from './jeSchedulesPayload';
4
+ import { generateJEOneTimeAccrualKey } from './jeScheduleHelper';
5
+ import { getJEScheduleKey, getJEScheduleTransactionDetailKeyPayload, toJEAccruedScheduledTransaction, toJEOneTimeAccrual, toJEScheduledTransaction, toScheduledJournalEntryState, } from './jeSchedulesPayload';
5
6
  export const initialState = {
6
7
  schedulesByTransactionKey: {},
7
8
  schedulesByAccruedJEScheduleKey: {},
9
+ oneTimeAccrualsByKey: {},
8
10
  };
9
11
  const jeSchedules = createSlice({
10
12
  name: 'jeSchedules',
@@ -109,15 +111,41 @@ const jeSchedules = createSlice({
109
111
  delete draft.schedulesByAccruedJEScheduleKey[JEScheduleKey];
110
112
  },
111
113
  },
114
+ // Writes directly, unlike updateAccruedJESchedules / updateJESchedules, which are no-op
115
+ // actions whose only job is to trigger the entity fan-out epic that fetches vendors,
116
+ // accounts, classes and users. An accrual denormalizes all of those as names on the document,
117
+ // so there is nothing to fan out to.
118
+ updateJEOneTimeAccruals: {
119
+ prepare(jeOneTimeAccrualsPayload) {
120
+ return {
121
+ payload: {
122
+ jeOneTimeAccrualsPayload,
123
+ },
124
+ };
125
+ },
126
+ reducer(draft, action) {
127
+ action.payload.jeOneTimeAccrualsPayload.forEach((accrualPayload) => {
128
+ const accrual = toJEOneTimeAccrual(accrualPayload);
129
+ draft.oneTimeAccrualsByKey[generateJEOneTimeAccrualKey(accrual.accrualId)] = accrual;
130
+ });
131
+ },
132
+ },
133
+ clearAllJEScheduleTransactions(draft) {
134
+ draft.schedulesByTransactionKey = {};
135
+ },
136
+ clearAllAccruedJESchedules(draft) {
137
+ draft.schedulesByAccruedJEScheduleKey = {};
138
+ },
112
139
  },
113
140
  extraReducers: (builder) => {
114
141
  builder.addCase(clearAll, (draft) => {
115
142
  draft.schedulesByAccruedJEScheduleKey = {};
116
143
  draft.schedulesByTransactionKey = {};
144
+ draft.oneTimeAccrualsByKey = {};
117
145
  });
118
146
  },
119
147
  });
120
- export const { updateJESchedules, updateAccruedJESchedules, updateJEScheduledTransaction, updateAccruedJEScheduledTransaction, updateJESchedulesDetails, updateAccruedJESchedulesDetails, deleteJESchedulesDetails, deleteAccruedJESchedulesDetails, } = jeSchedules.actions;
148
+ export const { updateJESchedules, updateAccruedJESchedules, updateJEScheduledTransaction, updateAccruedJEScheduledTransaction, updateJESchedulesDetails, updateAccruedJESchedulesDetails, deleteJESchedulesDetails, deleteAccruedJESchedulesDetails, clearAllAccruedJESchedules, clearAllJEScheduleTransactions, updateJEOneTimeAccruals, } = jeSchedules.actions;
121
149
  export default jeSchedules.reducer;
122
150
  /**
123
151
  * Helper functions
@@ -5,18 +5,34 @@ import { getClassById } from '../class/classSelector';
5
5
  import { getScheduleTransactionById } from '../transaction/transactionSelector';
6
6
  import { getUserByUserId } from '../user/userSelector';
7
7
  import { getVendorByVendorId } from '../vendor/vendorSelector';
8
+ // Takes the slice, not RootState: an accrual denormalizes its vendor, account and class names, so
9
+ // unlike getJEAccruedScheduleByJEScheduleKey this joins nothing.
10
+ //
11
+ // Spreads the stored entity rather than rebuilding it field by field. That is deliberate — the
12
+ // accrued joiner listed every field explicitly and silently dropped jeScheduleType, which made a
13
+ // whole tab render empty while its reducer test still passed. A spread cannot lose a field.
14
+ export const getJEOneTimeAccrualByKey = (jeOneTimeAccrualKey, jeSchedulesState) => {
15
+ const accrual = recordGet(jeSchedulesState.oneTimeAccrualsByKey, jeOneTimeAccrualKey);
16
+ if (accrual == null) {
17
+ return undefined;
18
+ }
19
+ return { ...accrual, jeOneTimeAccrualKey };
20
+ };
8
21
  export const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
9
22
  const { jeSchedulesState, vendorState, accountState, userState, classState } = state;
10
23
  const JEAccruedScheduleState = recordGet(jeSchedulesState.schedulesByAccruedJEScheduleKey, JEScheduleKey);
11
24
  if (JEAccruedScheduleState == null) {
12
25
  return undefined;
13
26
  }
14
- const { period, updatedByUserID: updatedBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, memo, recurringAmount, createTime, otherAttributes, } = JEAccruedScheduleState;
27
+ const { period, updatedByUserID: updatedBy, createdByUserID: createdBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, memo, recurringAmount, createTime, otherAttributes, jeScheduleType, } = JEAccruedScheduleState;
15
28
  const vendorDetails = getVendorByVendorId(vendorState, vendorId);
16
29
  if (vendorDetails == null) {
17
30
  throw new Error(`Vendor with ${vendorId} doesn't exist`);
18
31
  }
19
32
  const userDetails = updatedBy != null ? getUserByUserId(userState, updatedBy) : undefined;
33
+ // Resolved the same way the prepaid / fixed joiner does. Without it every accrued row rendered a
34
+ // hyphen under "Created by", even though the payload carries created_by.
35
+ const createdByUserDetails = createdBy != null ? getUserByUserId(userState, createdBy) : undefined;
20
36
  const accountCredit = jeCredit.accountId != null
21
37
  ? getAccountBase(accountState, jeCredit.accountId, 'account_list')
22
38
  : undefined;
@@ -35,14 +51,19 @@ export const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
35
51
  reportId: 'class_list',
36
52
  })
37
53
  : undefined;
54
+ const postedCount = scheduledJournalEntry.filter((sje) => sje.status.code === 'posted' || sje.status.code === 'recorded').length;
55
+ const lifecycleTotal = period ?? scheduledJournalEntry.length;
38
56
  return {
39
57
  jeScheduleId,
40
58
  otherAttributes,
41
59
  vendor: vendorDetails,
42
60
  updatedByUser: userDetails,
61
+ createdByUser: createdByUserDetails,
43
62
  updatedAt,
44
63
  currencyCode,
45
64
  currencySymbol,
65
+ lifecycleTotal,
66
+ postedCount,
46
67
  jeCredit: {
47
68
  accountingClass: classCredit,
48
69
  account: accountCredit,
@@ -60,6 +81,7 @@ export const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
60
81
  memo,
61
82
  createTime,
62
83
  recurringAmount,
84
+ jeScheduleType,
63
85
  jeAccruedScheduleKey: JEScheduleKey,
64
86
  balanceAsOfToday: balanceAsOfToday != null
65
87
  ? toAmount(balanceAsOfToday, currencyCode, currencySymbol)
@@ -70,7 +92,7 @@ export const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
70
92
  export const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTransactionKey, state) => {
71
93
  const { jeSchedulesState, vendorState, accountState, userState, classState, transactionState, } = state;
72
94
  const jeScheduleTransactionState = recordGet(jeSchedulesState.schedulesByTransactionKey, jeScheduleTransactionKey);
73
- const { period, updatedByUserID: updatedBy, createdByUserID: createdBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, baseTransaction, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, otherAttributes, jeScheduleType, aiSummaries, recommendations, } = jeScheduleTransactionState;
95
+ const { period, updatedByUserID: updatedBy, createdByUserID: createdBy, createTime, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, baseTransaction, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, otherAttributes, jeScheduleType, aiSummaries, confidenceScore, recommendations, recurringAmount, postedCount: postedCountFromServer, } = jeScheduleTransactionState;
74
96
  const vendorDetails = getVendorByVendorId(vendorState, vendorId);
75
97
  if (vendorDetails == null) {
76
98
  throw new Error(`Vendor with ${vendorId} doesn't exist`);
@@ -99,14 +121,24 @@ export const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTr
99
121
  reportId: 'class_list',
100
122
  })
101
123
  : undefined;
124
+ // The expense-automation response carries no scheduled journal entries for these rows, so the
125
+ // filter below counts an empty array and every schedule reported 0 posted. Prefer the count the
126
+ // server derives, and keep the filter for callers that do have entries (the detail page, and
127
+ // failed postings, which come with theirs).
128
+ const postedCount = postedCountFromServer ??
129
+ scheduledJournalEntry.filter((sje) => sje.status.code === 'posted' || sje.status.code === 'recorded').length;
130
+ const lifecycleTotal = period ?? scheduledJournalEntry.length;
102
131
  return {
103
132
  jeScheduleId,
104
133
  jeScheduleType,
134
+ recurringAmount,
105
135
  jeScheduleTransactionKey: jeScheduleTransactionKey,
106
136
  vendor: vendorDetails,
107
137
  updatedByUser: userDetails,
108
138
  updatedAt: updatedAt,
109
139
  period,
140
+ lifecycleTotal,
141
+ postedCount,
110
142
  balanceAsOfToday: balanceAsOfToday != null
111
143
  ? toAmount(balanceAsOfToday, currencyCode, currencySymbol)
112
144
  : undefined,
@@ -129,7 +161,9 @@ export const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTr
129
161
  },
130
162
  scheduledJournalEntry,
131
163
  aiSummaries,
164
+ confidenceScore,
132
165
  createdByUser: createdByUserDetails,
166
+ createTime,
133
167
  recommendations,
134
168
  };
135
169
  };
@@ -24,6 +24,92 @@ const SCHEDULE_STATUS_CODE = [
24
24
  'draft',
25
25
  ];
26
26
  export const toScheduleStatusCodeType = (v) => stringToUnion(v, SCHEDULE_STATUS_CODE);
27
+ // One-time accruals come from agent-je's Mongo `accruals` collection, not the JE schedule
28
+ // datastore, so they carry their own status vocabulary rather than SCHEDULE_STATUS_CODE.
29
+ // `posting` and `reversing` are transient claims held while a JE posts.
30
+ /**
31
+ * Mirrors agent-je's own status constants. `reverted` is the terminal state a manual revert writes
32
+ * alongside is_deleted; without it stringToUnion logs an error and passes the raw string through.
33
+ *
34
+ * There is deliberately no `ignored` member -- ignoring an accrual sets the `is_ignored` flag and
35
+ * leaves the status on `draft`.
36
+ */
37
+ const ONE_TIME_ACCRUAL_STATUS_CODE = [
38
+ 'draft',
39
+ 'posting',
40
+ 'posted',
41
+ 'posting_blocked',
42
+ 'reversing',
43
+ 'reversed',
44
+ 'reverted',
45
+ ];
46
+ export const toOneTimeAccrualStatusCodeType = (v) => stringToUnion(v, ONE_TIME_ACCRUAL_STATUS_CODE);
47
+ // Who created the accrual. This — not the creator's email — is the authoritative
48
+ // AI-vs-manual signal for the Method column.
49
+ const ONE_TIME_ACCRUAL_ORIGIN = ['agent', 'human'];
50
+ export const toOneTimeAccrualOriginType = (v) => stringToUnion(v, ONE_TIME_ACCRUAL_ORIGIN);
51
+ const ONE_TIME_ACCRUAL_AUTOMATION_TIER = ['manual', 'draft', 'auto'];
52
+ export const toOneTimeAccrualAutomationTierType = (v) => stringToUnion(v, ONE_TIME_ACCRUAL_AUTOMATION_TIER);
53
+ // How the accrual is allowed to reverse. The two are exclusive: a scheduled row reverses on
54
+ // expectedReversalDate and bills never drive it; an on_bill_match row reverses only when a bill
55
+ // is matched, which is why its lifecycle reads "Reverses on match" rather than showing a date.
56
+ const ONE_TIME_ACCRUAL_REVERSAL_POLICY = [
57
+ 'on_bill_match',
58
+ 'scheduled_date',
59
+ ];
60
+ export const toOneTimeAccrualReversalPolicyType = (v) => stringToUnion(v, ONE_TIME_ACCRUAL_REVERSAL_POLICY);
61
+ // What actually caused a reverse. Distinct from a *revert*, which soft-deletes the row and
62
+ // never sets this.
63
+ const ONE_TIME_ACCRUAL_REVERSAL_TRIGGER = [
64
+ 'bill_match',
65
+ 'scheduled_date',
66
+ 'manual_reverse',
67
+ ];
68
+ export const toOneTimeAccrualReversalTriggerType = (v) => stringToUnionStrict(v ?? '', ONE_TIME_ACCRUAL_REVERSAL_TRIGGER);
69
+ // Why a human told the AI Accountant not to accrue this month. The gateway validates against
70
+ // exactly this set, so it is a union rather than a free-text string.
71
+ const ONE_TIME_ACCRUAL_IGNORE_REASON = [
72
+ 'no_activity',
73
+ 'paused',
74
+ 'too_small',
75
+ 'need_invoice',
76
+ 'other_ignore',
77
+ ];
78
+ export const toOneTimeAccrualIgnoreReasonType = (v) => stringToUnion(v, ONE_TIME_ACCRUAL_IGNORE_REASON);
79
+ export const ALL_ONE_TIME_ACCRUAL_IGNORE_REASONS = ONE_TIME_ACCRUAL_IGNORE_REASON;
80
+ // Why a recommended prepaid / fixed-asset schedule is being dismissed. A different set from the
81
+ // accrual ignore reasons: the gateway validates each against its own list.
82
+ const JE_SCHEDULE_IGNORE_REASON = [
83
+ 'not_needed',
84
+ 'wrong_account',
85
+ 'duplicate',
86
+ 'already_handled',
87
+ 'other_ignore',
88
+ ];
89
+ export const toJEScheduleIgnoreReasonType = (v) => stringToUnion(v, JE_SCHEDULE_IGNORE_REASON);
90
+ export const ALL_JE_SCHEDULE_IGNORE_REASONS = JE_SCHEDULE_IGNORE_REASON;
91
+ // Why a posted prepaid / fixed-asset schedule is being undone. Note `not_accrual` is accrual-only
92
+ // and rejected here, and `created_by_mistake` is schedule-only.
93
+ const JE_SCHEDULE_REVERT_REASON = [
94
+ 'amount_off',
95
+ 'wrong_period',
96
+ 'duplicate',
97
+ 'created_by_mistake',
98
+ 'other_revert',
99
+ ];
100
+ export const toJEScheduleRevertReasonType = (v) => stringToUnion(v, JE_SCHEDULE_REVERT_REASON);
101
+ export const ALL_JE_SCHEDULE_REVERT_REASONS = JE_SCHEDULE_REVERT_REASON;
102
+ // Why a posted accrual is being undone. A disjoint set from the ignore reasons — the gateway
103
+ // validates each action against its own list and rejects the other's values.
104
+ const ONE_TIME_ACCRUAL_REVERT_REASON = [
105
+ 'amount_off',
106
+ 'wrong_period',
107
+ 'not_accrual',
108
+ 'duplicate',
109
+ 'other_revert',
110
+ ];
111
+ export const toOneTimeAccrualRevertReasonType = (v) => stringToUnion(v, ONE_TIME_ACCRUAL_REVERT_REASON);
112
+ export const ALL_ONE_TIME_ACCRUAL_REVERT_REASONS = ONE_TIME_ACCRUAL_REVERT_REASON;
27
113
  const JOURNAL_ENTRY_ERROR_CODE = [
28
114
  'vendor_deleted',
29
115
  'debit_category_deleted',
@@ -116,6 +116,9 @@ const ALL_SNACKBAR_MESSAGE_SECTIONS = [
116
116
  'save_schedule',
117
117
  'delete_schedule',
118
118
  'ignore_schedule',
119
+ 'revert_schedule',
120
+ 'ignore_accrual',
121
+ 'revert_accrual',
119
122
  'save_task_detail',
120
123
  'fetch_task_detail',
121
124
  'delete_task',
@@ -30,5 +30,7 @@ export const toScheduleTransaction = (payload, currency_code, currency_symbol) =
30
30
  currencySymbol: currency_symbol,
31
31
  },
32
32
  description: payload.transaction_description ?? undefined,
33
+ vendorId: payload.vendor_id ?? undefined,
34
+ vendorName: payload.vendor_name ?? undefined,
33
35
  };
34
36
  };