@zeniai/client-epic-state 5.0.69-betaML52 → 5.0.69-betaML6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
- package/lib/commonStateTypes/viewAndReport/viewAndReport.js +0 -2
- package/lib/entity/account/accountSelector.d.ts +0 -9
- package/lib/entity/account/accountSelector.js +1 -14
- package/lib/entity/account/accountState.d.ts +1 -1
- package/lib/entity/accountGroup/accountGroupState.d.ts +1 -1
- package/lib/entity/class/classReducer.d.ts +4 -4
- package/lib/entity/class/classState.d.ts +1 -1
- package/lib/entity/forecast/forecastState.d.ts +1 -1
- package/lib/entity/sectionAccountsView/sectionAccountsView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesViewReducer.d.ts +2 -2
- package/lib/entity/sectionProjectView/sectionProjectView.d.ts +1 -1
- package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +2 -2
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +0 -1
- package/lib/entity/tenant/clearAllEpic.d.ts +1 -2
- package/lib/entity/tenant/clearAllEpic.js +0 -2
- package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +0 -4
- package/lib/entity/transaction/payloadTypes/transactionPayload.js +10 -18
- package/lib/entity/transaction/stateTypes/transaction.d.ts +0 -3
- package/lib/epic.d.ts +2 -3
- package/lib/epic.js +2 -3
- package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +0 -2
- package/lib/esm/entity/account/accountSelector.js +0 -11
- package/lib/esm/entity/snackbar/snackbarTypes.js +0 -1
- package/lib/esm/entity/tenant/clearAllEpic.js +0 -2
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +10 -18
- package/lib/esm/epic.js +2 -3
- package/lib/esm/index.js +8 -9
- package/lib/esm/reducer.js +0 -3
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +0 -8
- package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +21 -1
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +117 -26
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +32 -9
- package/lib/esm/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +83 -0
- package/lib/esm/view/recommendation/recommendationHelper.js +29 -0
- package/lib/esm/view/recommendation/recommendationReducer.js +36 -1
- package/lib/esm/view/transactionDetail/epics/transactionDetailEpic.js +2 -14
- package/lib/esm/view/transactionDetail/transactionDetailReducer.js +95 -3
- package/lib/esm/view/transactionDetail/transactionDetailSelector.js +23 -6
- package/lib/index.d.ts +9 -9
- package/lib/index.js +36 -43
- package/lib/reducer.d.ts +0 -3
- package/lib/reducer.js +0 -3
- package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
- package/lib/view/billPayCard/billPayCardSelector.d.ts +1 -1
- package/lib/view/cardBalance/cardBalanceSelector.d.ts +1 -1
- package/lib/view/cashBalance/cashBalanceSelector.d.ts +1 -1
- package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +1 -1
- package/lib/view/cashPosition/cashPositionSelector.d.ts +1 -1
- package/lib/view/dashboard/dashboardReducer.d.ts +2 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.d.ts +1 -2
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +0 -8
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +2 -1
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +23 -2
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +15 -4
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +117 -26
- package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +3 -4
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +3 -1
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +33 -11
- package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +1 -0
- package/lib/view/financeStatement/financeStatementReducer.d.ts +1 -1
- package/lib/view/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
- package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.d.ts +9 -0
- package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +87 -0
- package/lib/view/recommendation/recommendationHelper.d.ts +9 -0
- package/lib/view/recommendation/recommendationHelper.js +31 -1
- package/lib/view/recommendation/recommendationReducer.d.ts +18 -1
- package/lib/view/recommendation/recommendationReducer.js +37 -2
- package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
- package/lib/view/reportsResync/reportsResyncReducer.d.ts +2 -2
- package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
- package/lib/view/topEx/topExSelector.d.ts +1 -1
- package/lib/view/transactionDetail/epics/transactionDetailEpic.d.ts +1 -2
- package/lib/view/transactionDetail/epics/transactionDetailEpic.js +2 -14
- package/lib/view/transactionDetail/transactionDetailPayload.d.ts +1 -1
- package/lib/view/transactionDetail/transactionDetailReducer.d.ts +12 -3
- package/lib/view/transactionDetail/transactionDetailReducer.js +96 -4
- package/lib/view/transactionDetail/transactionDetailSelector.d.ts +3 -6
- package/lib/view/transactionDetail/transactionDetailSelector.js +25 -7
- package/lib/view/transactionDetail/transactionDetailTypes.d.ts +1 -0
- package/package.json +1 -1
- package/lib/esm/view/createTransferEntry/createTransferEntryReducer.js +0 -72
- package/lib/esm/view/createTransferEntry/createTransferEntrySelector.js +0 -64
- package/lib/esm/view/createTransferEntry/createTransferEntryState.js +0 -17
- package/lib/esm/view/createTransferEntry/epics/createTransferEntryEpic.js +0 -130
- package/lib/esm/view/createTransferEntry/epics/fetchTransferAccountsEpic.js +0 -36
- package/lib/view/createTransferEntry/createTransferEntryReducer.d.ts +0 -32
- package/lib/view/createTransferEntry/createTransferEntryReducer.js +0 -76
- package/lib/view/createTransferEntry/createTransferEntrySelector.d.ts +0 -39
- package/lib/view/createTransferEntry/createTransferEntrySelector.js +0 -69
- package/lib/view/createTransferEntry/createTransferEntryState.d.ts +0 -30
- package/lib/view/createTransferEntry/createTransferEntryState.js +0 -20
- package/lib/view/createTransferEntry/epics/createTransferEntryEpic.d.ts +0 -11
- package/lib/view/createTransferEntry/epics/createTransferEntryEpic.js +0 -134
- package/lib/view/createTransferEntry/epics/fetchTransferAccountsEpic.d.ts +0 -14
- package/lib/view/createTransferEntry/epics/fetchTransferAccountsEpic.js +0 -40
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
var _a;
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.setIsVendorUpdateAllChecked = exports.updateVendorBulkRecommendationsFetchStatus = exports.updateLatestSelectedEntity = exports.resetAllLineItemsToVendor = exports.updateVendorToAllLineItems = exports.updateLocalDataWithTransactionsUpdateWithVendorCheckbox = exports.resetSelectedCustomer = exports.resetVendor = exports.updateSelectedCustomer = exports.updateSelectedVendor = exports.removeEntityRecommendationForLineIdForTransactionDetail = exports.setEntityRecommendationForLineIdsForTransactionDetail = exports.setAllLineItemsLocalDataIsUpdateAllChecked = exports.setAllLineItemsToCategoryClassInLocalData = exports.resetLineItemsCategoryClassInLocalData = exports.clearTransactionDetailLocalData = exports.saveTransactionDetailLocalData = exports.initializeTransactionDetailLocalData = exports.saveTransactionDetail = exports.updateTransactionStateIfUpdateActionNotAllowed = exports.updateStatusConsolidatedSaveTransactionDetail = exports.updateStatusForTransactionNotMiscategorizedUpdate = exports.deleteTransactionAttachmentSuccess = exports.deleteTransactionAttachmentFailure = exports.deleteTransactionAttachment = exports.markTransactionAsNotMiscategorized = exports.clearTransactionDetailSaveStatus = exports.updateTransactionDetailSaveStatus = exports.updateTransactionDetail = exports.uploadMissingAttachmentSuccess = exports.clearTransactionDetail = exports.removeTransactionDetail = exports.updateTransactionDetailFetchState = exports.fetchTransactionDetail = exports.downloadAccountingProviderAttachmentFailure = exports.downloadAccountingProviderAttachmentSuccess = exports.downloadAccountingProviderAttachment = exports.initialState = void 0;
|
|
7
|
+
exports.setIsVendorUpdateAllChecked = exports.updateVendorBulkRecommendationsFetchStatus = exports.updateLatestSelectedEntity = exports.resetAllLineItemsToVendor = exports.updateVendorToAllLineItems = exports.updateLocalDataWithTransactionsUpdateWithVendorCheckbox = exports.resetSelectedCustomer = exports.resetVendor = exports.updateSelectedCustomer = exports.updateSelectedVendor = exports.removeEntityRecommendationForLineIdForTransactionDetail = exports.markCategoryClassRecommendationsFailureForTransactionDetail = exports.markCategoryClassRecommendationsCompletedForTransactionDetail = exports.markCategoryClassRecommendationsInProgressForTransactionDetail = exports.setEntityRecommendationForLineIdsForTransactionDetail = exports.setAllLineItemsLocalDataIsUpdateAllChecked = exports.setAllLineItemsToCategoryClassInLocalData = exports.resetLineItemsCategoryClassInLocalData = exports.clearTransactionDetailLocalData = exports.saveTransactionDetailLocalData = exports.initializeTransactionDetailLocalData = exports.saveTransactionDetail = exports.updateTransactionStateIfUpdateActionNotAllowed = exports.updateStatusConsolidatedSaveTransactionDetail = exports.updateStatusForTransactionNotMiscategorizedUpdate = exports.deleteTransactionAttachmentSuccess = exports.deleteTransactionAttachmentFailure = exports.deleteTransactionAttachment = exports.markTransactionAsNotMiscategorized = exports.clearTransactionDetailSaveStatus = exports.updateTransactionDetailSaveStatus = exports.updateTransactionDetail = exports.uploadMissingAttachmentSuccess = exports.clearTransactionDetail = exports.removeTransactionDetail = exports.updateTransactionDetailFetchState = exports.fetchTransactionDetail = exports.downloadAccountingProviderAttachmentFailure = exports.downloadAccountingProviderAttachmentSuccess = exports.downloadAccountingProviderAttachment = exports.initialState = void 0;
|
|
8
8
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
9
9
|
const get_1 = __importDefault(require("lodash/get"));
|
|
10
10
|
const entity_1 = require("../../entity/genericEntity/entity");
|
|
@@ -57,12 +57,11 @@ const transactionDetail = (0, toolkit_1.createSlice)({
|
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
|
-
prepare(transactionId, cacheOverride = false
|
|
60
|
+
prepare(transactionId, cacheOverride = false) {
|
|
61
61
|
return {
|
|
62
62
|
payload: {
|
|
63
63
|
transactionId,
|
|
64
64
|
cacheOverride,
|
|
65
|
-
isCreateTransferEntryFromExpenseEnabled,
|
|
66
65
|
},
|
|
67
66
|
};
|
|
68
67
|
},
|
|
@@ -373,6 +372,21 @@ const transactionDetail = (0, toolkit_1.createSlice)({
|
|
|
373
372
|
const detail = (0, get_1.default)(draft.transactionDetailById, key, undefined);
|
|
374
373
|
if (detail != null) {
|
|
375
374
|
const newLocalData = (0, transactionDetailLocalDataHelper_1.setEntityRecommendationForLineIdInLocalData)(transaction, detail.transactionDetailLocalData, action.payload.entity, lineIds, uncategorizedIncomeExpense, recommendationWithCOTByLineId);
|
|
375
|
+
// Release the per-line fetch flag for every line this fetch
|
|
376
|
+
// covered so the inline skeleton resolves and the page-level
|
|
377
|
+
// Save button can re-enable.
|
|
378
|
+
lineIds.forEach((lineId) => {
|
|
379
|
+
const lineItem = newLocalData.lineItemById[lineId];
|
|
380
|
+
if (lineItem != null) {
|
|
381
|
+
newLocalData.lineItemById[lineId] = {
|
|
382
|
+
...lineItem,
|
|
383
|
+
categoryClassRecommendationsFetchState: {
|
|
384
|
+
fetchState: 'Completed',
|
|
385
|
+
error: undefined,
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
});
|
|
376
390
|
draft.transactionDetailById[key] = {
|
|
377
391
|
...detail,
|
|
378
392
|
transactionDetailLocalData: newLocalData,
|
|
@@ -393,6 +407,84 @@ const transactionDetail = (0, toolkit_1.createSlice)({
|
|
|
393
407
|
};
|
|
394
408
|
},
|
|
395
409
|
},
|
|
410
|
+
// Start arm of the line-update recommendations fetch for the detail
|
|
411
|
+
// page. Flips covered lines to In-Progress; detail page has no
|
|
412
|
+
// checkbox, so no auto-uncheck side effect.
|
|
413
|
+
markCategoryClassRecommendationsInProgressForTransactionDetail: {
|
|
414
|
+
reducer(draft, action) {
|
|
415
|
+
const { transactionId, lineIds } = action.payload;
|
|
416
|
+
const key = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
|
|
417
|
+
const detail = (0, get_1.default)(draft.transactionDetailById, key, undefined);
|
|
418
|
+
if (detail != null) {
|
|
419
|
+
lineIds.forEach((lineId) => {
|
|
420
|
+
const lineItem = detail.transactionDetailLocalData.lineItemById[lineId];
|
|
421
|
+
if (lineItem != null) {
|
|
422
|
+
detail.transactionDetailLocalData.lineItemById[lineId] = {
|
|
423
|
+
...lineItem,
|
|
424
|
+
categoryClassRecommendationsFetchState: {
|
|
425
|
+
fetchState: 'In-Progress',
|
|
426
|
+
error: undefined,
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
prepare(transactionId, lineIds) {
|
|
434
|
+
return { payload: { transactionId, lineIds } };
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
// Completed arm. Used when the HTTP call succeeded but the server
|
|
438
|
+
// returned no per-line recommendations — still need to release the
|
|
439
|
+
// In-Progress flag.
|
|
440
|
+
markCategoryClassRecommendationsCompletedForTransactionDetail: {
|
|
441
|
+
reducer(draft, action) {
|
|
442
|
+
const { transactionId, lineIds } = action.payload;
|
|
443
|
+
const key = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
|
|
444
|
+
const detail = (0, get_1.default)(draft.transactionDetailById, key, undefined);
|
|
445
|
+
if (detail != null) {
|
|
446
|
+
lineIds.forEach((lineId) => {
|
|
447
|
+
const lineItem = detail.transactionDetailLocalData.lineItemById[lineId];
|
|
448
|
+
if (lineItem != null) {
|
|
449
|
+
detail.transactionDetailLocalData.lineItemById[lineId] = {
|
|
450
|
+
...lineItem,
|
|
451
|
+
categoryClassRecommendationsFetchState: {
|
|
452
|
+
fetchState: 'Completed',
|
|
453
|
+
error: undefined,
|
|
454
|
+
},
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
prepare(transactionId, lineIds) {
|
|
461
|
+
return { payload: { transactionId, lineIds } };
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
markCategoryClassRecommendationsFailureForTransactionDetail: {
|
|
465
|
+
reducer(draft, action) {
|
|
466
|
+
const { transactionId, lineIds, error } = action.payload;
|
|
467
|
+
const key = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
|
|
468
|
+
const detail = (0, get_1.default)(draft.transactionDetailById, key, undefined);
|
|
469
|
+
if (detail != null) {
|
|
470
|
+
lineIds.forEach((lineId) => {
|
|
471
|
+
const lineItem = detail.transactionDetailLocalData.lineItemById[lineId];
|
|
472
|
+
if (lineItem != null) {
|
|
473
|
+
detail.transactionDetailLocalData.lineItemById[lineId] = {
|
|
474
|
+
...lineItem,
|
|
475
|
+
categoryClassRecommendationsFetchState: {
|
|
476
|
+
fetchState: 'Error',
|
|
477
|
+
error,
|
|
478
|
+
},
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
prepare(transactionId, lineIds, error) {
|
|
485
|
+
return { payload: { transactionId, lineIds, error } };
|
|
486
|
+
},
|
|
487
|
+
},
|
|
396
488
|
removeEntityRecommendationForLineIdForTransactionDetail: {
|
|
397
489
|
reducer(draft, action) {
|
|
398
490
|
const { transaction, lineId } = action.payload;
|
|
@@ -664,7 +756,7 @@ const transactionDetail = (0, toolkit_1.createSlice)({
|
|
|
664
756
|
},
|
|
665
757
|
},
|
|
666
758
|
});
|
|
667
|
-
_a = transactionDetail.actions, exports.downloadAccountingProviderAttachment = _a.downloadAccountingProviderAttachment, exports.downloadAccountingProviderAttachmentSuccess = _a.downloadAccountingProviderAttachmentSuccess, exports.downloadAccountingProviderAttachmentFailure = _a.downloadAccountingProviderAttachmentFailure, exports.fetchTransactionDetail = _a.fetchTransactionDetail, exports.updateTransactionDetailFetchState = _a.updateTransactionDetailFetchState, exports.removeTransactionDetail = _a.removeTransactionDetail, exports.clearTransactionDetail = _a.clearTransactionDetail, exports.uploadMissingAttachmentSuccess = _a.uploadMissingAttachmentSuccess, exports.updateTransactionDetail = _a.updateTransactionDetail, exports.updateTransactionDetailSaveStatus = _a.updateTransactionDetailSaveStatus, exports.clearTransactionDetailSaveStatus = _a.clearTransactionDetailSaveStatus, exports.markTransactionAsNotMiscategorized = _a.markTransactionAsNotMiscategorized, exports.deleteTransactionAttachment = _a.deleteTransactionAttachment, exports.deleteTransactionAttachmentFailure = _a.deleteTransactionAttachmentFailure, exports.deleteTransactionAttachmentSuccess = _a.deleteTransactionAttachmentSuccess, exports.updateStatusForTransactionNotMiscategorizedUpdate = _a.updateStatusForTransactionNotMiscategorizedUpdate, exports.updateStatusConsolidatedSaveTransactionDetail = _a.updateStatusConsolidatedSaveTransactionDetail, exports.updateTransactionStateIfUpdateActionNotAllowed = _a.updateTransactionStateIfUpdateActionNotAllowed, exports.saveTransactionDetail = _a.saveTransactionDetail, exports.initializeTransactionDetailLocalData = _a.initializeTransactionDetailLocalData, exports.saveTransactionDetailLocalData = _a.saveTransactionDetailLocalData, exports.clearTransactionDetailLocalData = _a.clearTransactionDetailLocalData, exports.resetLineItemsCategoryClassInLocalData = _a.resetLineItemsCategoryClassInLocalData, exports.setAllLineItemsToCategoryClassInLocalData = _a.setAllLineItemsToCategoryClassInLocalData, exports.setAllLineItemsLocalDataIsUpdateAllChecked = _a.setAllLineItemsLocalDataIsUpdateAllChecked, exports.setEntityRecommendationForLineIdsForTransactionDetail = _a.setEntityRecommendationForLineIdsForTransactionDetail, exports.removeEntityRecommendationForLineIdForTransactionDetail = _a.removeEntityRecommendationForLineIdForTransactionDetail, exports.updateSelectedVendor = _a.updateSelectedVendor, exports.updateSelectedCustomer = _a.updateSelectedCustomer, exports.resetVendor = _a.resetVendor, exports.resetSelectedCustomer = _a.resetSelectedCustomer, exports.updateLocalDataWithTransactionsUpdateWithVendorCheckbox = _a.updateLocalDataWithTransactionsUpdateWithVendorCheckbox, exports.updateVendorToAllLineItems = _a.updateVendorToAllLineItems, exports.resetAllLineItemsToVendor = _a.resetAllLineItemsToVendor, exports.updateLatestSelectedEntity = _a.updateLatestSelectedEntity, exports.updateVendorBulkRecommendationsFetchStatus = _a.updateVendorBulkRecommendationsFetchStatus, exports.setIsVendorUpdateAllChecked = _a.setIsVendorUpdateAllChecked;
|
|
759
|
+
_a = transactionDetail.actions, exports.downloadAccountingProviderAttachment = _a.downloadAccountingProviderAttachment, exports.downloadAccountingProviderAttachmentSuccess = _a.downloadAccountingProviderAttachmentSuccess, exports.downloadAccountingProviderAttachmentFailure = _a.downloadAccountingProviderAttachmentFailure, exports.fetchTransactionDetail = _a.fetchTransactionDetail, exports.updateTransactionDetailFetchState = _a.updateTransactionDetailFetchState, exports.removeTransactionDetail = _a.removeTransactionDetail, exports.clearTransactionDetail = _a.clearTransactionDetail, exports.uploadMissingAttachmentSuccess = _a.uploadMissingAttachmentSuccess, exports.updateTransactionDetail = _a.updateTransactionDetail, exports.updateTransactionDetailSaveStatus = _a.updateTransactionDetailSaveStatus, exports.clearTransactionDetailSaveStatus = _a.clearTransactionDetailSaveStatus, exports.markTransactionAsNotMiscategorized = _a.markTransactionAsNotMiscategorized, exports.deleteTransactionAttachment = _a.deleteTransactionAttachment, exports.deleteTransactionAttachmentFailure = _a.deleteTransactionAttachmentFailure, exports.deleteTransactionAttachmentSuccess = _a.deleteTransactionAttachmentSuccess, exports.updateStatusForTransactionNotMiscategorizedUpdate = _a.updateStatusForTransactionNotMiscategorizedUpdate, exports.updateStatusConsolidatedSaveTransactionDetail = _a.updateStatusConsolidatedSaveTransactionDetail, exports.updateTransactionStateIfUpdateActionNotAllowed = _a.updateTransactionStateIfUpdateActionNotAllowed, exports.saveTransactionDetail = _a.saveTransactionDetail, exports.initializeTransactionDetailLocalData = _a.initializeTransactionDetailLocalData, exports.saveTransactionDetailLocalData = _a.saveTransactionDetailLocalData, exports.clearTransactionDetailLocalData = _a.clearTransactionDetailLocalData, exports.resetLineItemsCategoryClassInLocalData = _a.resetLineItemsCategoryClassInLocalData, exports.setAllLineItemsToCategoryClassInLocalData = _a.setAllLineItemsToCategoryClassInLocalData, exports.setAllLineItemsLocalDataIsUpdateAllChecked = _a.setAllLineItemsLocalDataIsUpdateAllChecked, exports.setEntityRecommendationForLineIdsForTransactionDetail = _a.setEntityRecommendationForLineIdsForTransactionDetail, exports.markCategoryClassRecommendationsInProgressForTransactionDetail = _a.markCategoryClassRecommendationsInProgressForTransactionDetail, exports.markCategoryClassRecommendationsCompletedForTransactionDetail = _a.markCategoryClassRecommendationsCompletedForTransactionDetail, exports.markCategoryClassRecommendationsFailureForTransactionDetail = _a.markCategoryClassRecommendationsFailureForTransactionDetail, exports.removeEntityRecommendationForLineIdForTransactionDetail = _a.removeEntityRecommendationForLineIdForTransactionDetail, exports.updateSelectedVendor = _a.updateSelectedVendor, exports.updateSelectedCustomer = _a.updateSelectedCustomer, exports.resetVendor = _a.resetVendor, exports.resetSelectedCustomer = _a.resetSelectedCustomer, exports.updateLocalDataWithTransactionsUpdateWithVendorCheckbox = _a.updateLocalDataWithTransactionsUpdateWithVendorCheckbox, exports.updateVendorToAllLineItems = _a.updateVendorToAllLineItems, exports.resetAllLineItemsToVendor = _a.resetAllLineItemsToVendor, exports.updateLatestSelectedEntity = _a.updateLatestSelectedEntity, exports.updateVendorBulkRecommendationsFetchStatus = _a.updateVendorBulkRecommendationsFetchStatus, exports.setIsVendorUpdateAllChecked = _a.setIsVendorUpdateAllChecked;
|
|
668
760
|
exports.default = transactionDetail.reducer;
|
|
669
761
|
function getUpdatedEntityLocalData(detail, updates, entity, resetRecommendations, type) {
|
|
670
762
|
const key = type === 'customer' ? 'customerUpdates' : 'vendorUpdates';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { NestedAccountHierarchyForReport } from '../../commonStateTypes/accountView/nestedAccountID';
|
|
2
2
|
import { NestedClassHierarchyForReport } from '../../commonStateTypes/classesView/nestedClassID';
|
|
3
|
-
import {
|
|
3
|
+
import { FetchStateAndError } from '../../commonStateTypes/common';
|
|
4
4
|
import { SelectorView } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
5
|
-
import { AccountBase } from '../../entity/account/accountState';
|
|
6
5
|
import { TransactionID } from '../../entity/transaction/stateTypes/transaction';
|
|
7
6
|
import { SupportedTransactionWithCOT } from '../../entity/transaction/transactionState';
|
|
8
7
|
import { Vendor } from '../../entity/vendor/vendorState';
|
|
@@ -18,23 +17,21 @@ export interface TransactionDetailReport extends SelectorView {
|
|
|
18
17
|
allVendors: Vendor[];
|
|
19
18
|
classHierarchyList: NestedClassHierarchyForReport[];
|
|
20
19
|
classList: ClassListSelectorView;
|
|
21
|
-
createTransferEntryStatus: FetchState;
|
|
22
|
-
/** Resolved credit-card pool for credit_card_payment transfer drawer. */
|
|
23
|
-
creditCardTransferAccountsList: AccountBase[];
|
|
24
20
|
deleteStatusByAttachmentName: Record<string, FetchStateAndError>;
|
|
21
|
+
hasInFlightCategoryClassRecommendations: boolean;
|
|
25
22
|
isAccountingClassesEnabled: boolean;
|
|
26
23
|
isAccountingProjectsEnabled: boolean;
|
|
27
24
|
linkedTransactions: SupportedTransactionWithCOT[];
|
|
28
25
|
projectList: ProjectListSelectorView;
|
|
29
26
|
transactionDetailLocalData: TransactionDetailLocalData;
|
|
30
27
|
transactionDetailUpdateStatus: FetchStateAndError;
|
|
31
|
-
transferAccounts: AccountBase[];
|
|
32
28
|
isUpdateNotAllowed?: boolean;
|
|
33
29
|
transaction?: SupportedTransactionWithCOT;
|
|
34
30
|
}
|
|
35
31
|
export interface VendorDetailsView extends SelectorView {
|
|
36
32
|
vendors: Vendor[];
|
|
37
33
|
}
|
|
34
|
+
export declare const getDetailInFlightRecommendations: (state: RootState, transactionId: TransactionID) => boolean;
|
|
38
35
|
export declare const getTransactionDetail: (state: RootState, transactionId: TransactionID, fetchLinkedTransactions?: boolean) => TransactionDetailReport;
|
|
39
36
|
export declare function getTransactionDetailForTransaction(rootState: RootState, transactionId: TransactionID): TransactionDetailReport | undefined;
|
|
40
37
|
export declare const getInitialUpdatablePeriodsForTransactionRecommendations: (companyIncorporationDate?: ZeniDate, bookCloseDate?: ZeniDate) => {
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getInitialUpdatablePeriodsForTransactionRecommendations = exports.getTransactionDetail = void 0;
|
|
6
|
+
exports.getInitialUpdatablePeriodsForTransactionRecommendations = exports.getTransactionDetail = exports.getDetailInFlightRecommendations = void 0;
|
|
7
7
|
exports.getTransactionDetailForTransaction = getTransactionDetailForTransaction;
|
|
8
8
|
const get_1 = __importDefault(require("lodash/get"));
|
|
9
9
|
const reduceFetchState_1 = require("../../commonStateTypes/reduceFetchState");
|
|
@@ -15,11 +15,31 @@ const vendorSelector_1 = require("../../entity/vendor/vendorSelector");
|
|
|
15
15
|
const zeniDayJS_1 = require("../../zeniDayJS");
|
|
16
16
|
const accountListSelector_1 = require("../accountList/accountListSelector");
|
|
17
17
|
const classListSelector_1 = require("../classList/classListSelector");
|
|
18
|
-
const createTransferEntrySelector_1 = require("../createTransferEntry/createTransferEntrySelector");
|
|
19
18
|
const projectListSelector_1 = require("../projectList/projectListSelector");
|
|
20
19
|
const transactionDetailState_1 = require("./transactionDetailState");
|
|
20
|
+
// "Any line on this transaction is fetching category/class recommendations?"
|
|
21
|
+
// Inlined as a plain function because the upstream selector
|
|
22
|
+
// `getTransactionDetail` is also un-memoized and the iteration is O(lines)
|
|
23
|
+
// — typically <10. Exported standalone so consumers that only need the
|
|
24
|
+
// flag (e.g. footer save-disable) can avoid materializing the whole
|
|
25
|
+
// detail report.
|
|
26
|
+
const getDetailInFlightRecommendations = (state, transactionId) => {
|
|
27
|
+
const detailKey = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
|
|
28
|
+
const detail = (0, get_1.default)(state.transactionDetailState.transactionDetailById, detailKey, undefined);
|
|
29
|
+
if (detail == null) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
for (const lineItem of Object.values(detail.transactionDetailLocalData.lineItemById)) {
|
|
33
|
+
if (lineItem.categoryClassRecommendationsFetchState?.fetchState ===
|
|
34
|
+
'In-Progress') {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
};
|
|
40
|
+
exports.getDetailInFlightRecommendations = getDetailInFlightRecommendations;
|
|
21
41
|
const getTransactionDetail = (state, transactionId, fetchLinkedTransactions = true) => {
|
|
22
|
-
const { transactionDetailState, transactionState, vendorState, vendorListState, accountState, classState, classListState, accountListState,
|
|
42
|
+
const { transactionDetailState, transactionState, vendorState, vendorListState, accountState, classState, classListState, accountListState, projectState, projectListState, } = state;
|
|
23
43
|
const detailKey = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
|
|
24
44
|
const transactionDetail = (0, get_1.default)(transactionDetailState.transactionDetailById, detailKey);
|
|
25
45
|
let fetchState = {
|
|
@@ -86,7 +106,7 @@ const getTransactionDetail = (state, transactionId, fetchLinkedTransactions = tr
|
|
|
86
106
|
: [];
|
|
87
107
|
const transactionDetailAnyUpdateStatus = reduceUpdateFetchStates(transactionDetail);
|
|
88
108
|
const vendors = (0, vendorSelector_1.getVendorsByVendorIds)(vendorState, vendorListState.vendorIds);
|
|
89
|
-
const
|
|
109
|
+
const hasInFlightCategoryClassRecommendations = (0, exports.getDetailInFlightRecommendations)(state, transactionId);
|
|
90
110
|
return {
|
|
91
111
|
reportId: 'transaction_detail',
|
|
92
112
|
reportTitle: 'Transaction Detail',
|
|
@@ -102,10 +122,8 @@ const getTransactionDetail = (state, transactionId, fetchLinkedTransactions = tr
|
|
|
102
122
|
classHierarchyList,
|
|
103
123
|
accountsHierarchyList,
|
|
104
124
|
classList: classList,
|
|
125
|
+
hasInFlightCategoryClassRecommendations,
|
|
105
126
|
isAccountingClassesEnabled,
|
|
106
|
-
createTransferEntryStatus: createTransferEntryState.createTransferEntryStatus,
|
|
107
|
-
creditCardTransferAccountsList,
|
|
108
|
-
transferAccounts: transferAccountsList,
|
|
109
127
|
isAccountingProjectsEnabled,
|
|
110
128
|
projectList,
|
|
111
129
|
isUpdateNotAllowed: transactionDetail?.isUpdateNotAllowed,
|
|
@@ -14,6 +14,7 @@ export interface TransactionDetailLineItemData extends TransactionLineBase {
|
|
|
14
14
|
isClassMiscategorized: boolean;
|
|
15
15
|
account?: AccountBase;
|
|
16
16
|
billable?: BillableStatus;
|
|
17
|
+
categoryClassRecommendationsFetchState?: FetchStateAndError;
|
|
17
18
|
class?: ClassBase;
|
|
18
19
|
customer?: CustomerBase;
|
|
19
20
|
isCategoryUpdateSelected?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.0.69-
|
|
3
|
+
"version": "5.0.69-betaML6",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
-
import { initialCreateTransferEntryState, } from './createTransferEntryState';
|
|
3
|
-
export const initialState = initialCreateTransferEntryState;
|
|
4
|
-
const createTransferEntrySlice = createSlice({
|
|
5
|
-
name: 'createTransferEntry',
|
|
6
|
-
initialState,
|
|
7
|
-
reducers: {
|
|
8
|
-
fetchAccountsForTransferFlow(draft, action) {
|
|
9
|
-
draft.transferAccountsByType[action.payload.kind].fetchState =
|
|
10
|
-
'In-Progress';
|
|
11
|
-
},
|
|
12
|
-
updateAccountsForTransferFlow(draft, action) {
|
|
13
|
-
const slice = draft.transferAccountsByType[action.payload.kind];
|
|
14
|
-
slice.fetchState = 'Completed';
|
|
15
|
-
slice.accountIds = action.payload.accountIds;
|
|
16
|
-
},
|
|
17
|
-
updateAccountsForTransferFlowFailure(draft, action) {
|
|
18
|
-
draft.transferAccountsByType[action.payload.kind].fetchState = 'Error';
|
|
19
|
-
},
|
|
20
|
-
createTransferEntry: {
|
|
21
|
-
prepare(payload) {
|
|
22
|
-
return { payload };
|
|
23
|
-
},
|
|
24
|
-
/**
|
|
25
|
-
* Defense-in-depth: clear any stale `lastTransferEntryReplacement` on a
|
|
26
|
-
* fresh dispatch so a second `createTransferEntry` never inherits the
|
|
27
|
-
* previous run's replacement signal (e.g. if the prior `timer(0)` cleanup
|
|
28
|
-
* never fired). Mirrors the host hook's `consumedReplacementRef` guard
|
|
29
|
-
* (see `useTransferEntryRouteReplacement` in zeni-web-app-ui).
|
|
30
|
-
*/
|
|
31
|
-
reducer(draft) {
|
|
32
|
-
draft.createTransferEntryStatus = 'In-Progress';
|
|
33
|
-
draft.lastTransferEntryReplacement = undefined;
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
createTransferEntrySuccess(draft) {
|
|
37
|
-
draft.createTransferEntryStatus = 'Completed';
|
|
38
|
-
},
|
|
39
|
-
createTransferEntryFailure(draft) {
|
|
40
|
-
draft.createTransferEntryStatus = 'Error';
|
|
41
|
-
},
|
|
42
|
-
resetCreateTransferEntryStatus(draft) {
|
|
43
|
-
draft.createTransferEntryStatus = 'Not-Started';
|
|
44
|
-
},
|
|
45
|
-
createTransferEntryReplacedTransaction: {
|
|
46
|
-
prepare(previousTransactionId, newTransactionId) {
|
|
47
|
-
return { payload: { newTransactionId, previousTransactionId } };
|
|
48
|
-
},
|
|
49
|
-
reducer(draft, action) {
|
|
50
|
-
draft.lastTransferEntryReplacement = action.payload;
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
/**
|
|
54
|
-
* One-shot acknowledgement: the host has consumed the route-replacement
|
|
55
|
-
* signal and navigated to the new transaction url, so we can drop the
|
|
56
|
-
* record. Re-dispatching is idempotent.
|
|
57
|
-
*/
|
|
58
|
-
clearTransferEntryRouteReplacement(draft) {
|
|
59
|
-
draft.lastTransferEntryReplacement = undefined;
|
|
60
|
-
},
|
|
61
|
-
/**
|
|
62
|
-
* Full slice reset. Dispatched from `clearAllEpic` on tenant switch so
|
|
63
|
-
* stale per-tenant state (account-id pools, status, replacement signal)
|
|
64
|
-
* doesn't bleed across tenants.
|
|
65
|
-
*/
|
|
66
|
-
clearCreateTransferEntry(draft) {
|
|
67
|
-
Object.assign(draft, initialState);
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
export const { fetchAccountsForTransferFlow, updateAccountsForTransferFlow, updateAccountsForTransferFlowFailure, createTransferEntry, createTransferEntrySuccess, createTransferEntryFailure, resetCreateTransferEntryStatus, createTransferEntryReplacedTransaction, clearTransferEntryRouteReplacement, clearCreateTransferEntry, } = createTransferEntrySlice.actions;
|
|
72
|
-
export default createTransferEntrySlice.reducer;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
-
import { getAccountBase, getAccountBaseForCreditCardTransferAccounts, getAccountBaseForTransferAccounts, } from '../../entity/account/accountSelector';
|
|
3
|
-
import { getAccountList } from '../accountList/accountListSelector';
|
|
4
|
-
export function getCreateTransferEntryStatus(state) {
|
|
5
|
-
return state.createTransferEntryState.createTransferEntryStatus;
|
|
6
|
-
}
|
|
7
|
-
export function getLastTransferEntryReplacement(state) {
|
|
8
|
-
return state.createTransferEntryState.lastTransferEntryReplacement;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Shared resolver for the credit/debit dropdowns in the transfer drawer.
|
|
12
|
-
*
|
|
13
|
-
* Resolution policy (intentional):
|
|
14
|
-
* 1. Prefer the dedicated API fetch results (`transferEntryEligible` for the
|
|
15
|
-
* debit pool, `creditCardOnlyEligible` for the credit-card-payment credit
|
|
16
|
-
* pool).
|
|
17
|
-
* 2. If the dedicated fetch returns an empty list while the COA is loaded,
|
|
18
|
-
* fall back to the COA: the full account list for `transferEntryEligible`,
|
|
19
|
-
* and COA accounts filtered to `credit_card` for `creditCardOnlyEligible`.
|
|
20
|
-
* This keeps the dropdown populated for older tenants where the dedicated
|
|
21
|
-
* endpoints haven't been backfilled yet.
|
|
22
|
-
*
|
|
23
|
-
* Intent — what this selector deliberately does NOT do:
|
|
24
|
-
* - Does NOT distinguish "fetch in-flight" / "fetch errored" / "fetch returned
|
|
25
|
-
* empty" — all three collapse to the COA fallback. The product preference
|
|
26
|
-
* is "always show something selectable" over "show a spinner that may never
|
|
27
|
-
* resolve". Loading/error UI belongs in the view layer; if you need a
|
|
28
|
-
* spinner, observe the `fetchState` on `transferAccountsByType[kind]`
|
|
29
|
-
* separately rather than changing the resolution policy here.
|
|
30
|
-
* - Does NOT enforce "API result is authoritative even if empty" — a tenant
|
|
31
|
-
* whose dedicated endpoint is correctly returning `[]` (e.g. no eligible
|
|
32
|
-
* transfer destinations) will still see the COA. That trade-off is
|
|
33
|
-
* accepted because the alternative blocks the user from picking anything;
|
|
34
|
-
* the backend distinguishes "no result" from "endpoint not implemented" by
|
|
35
|
-
* surfacing an error response, which the view layer handles separately.
|
|
36
|
-
*
|
|
37
|
-
* Memoized with reselect so consuming view-models don't recompute on every
|
|
38
|
-
* unrelated state change.
|
|
39
|
-
*/
|
|
40
|
-
export const getResolvedTransferAccounts = createSelector([
|
|
41
|
-
(state) => state.accountState,
|
|
42
|
-
(state) => state.accountListState,
|
|
43
|
-
(state) => state.createTransferEntryState.transferAccountsByType
|
|
44
|
-
.transferEntryEligible.accountIds,
|
|
45
|
-
(state) => state.createTransferEntryState.transferAccountsByType
|
|
46
|
-
.creditCardOnlyEligible.accountIds,
|
|
47
|
-
], (accountState, accountListState, transferEligibleIds, creditCardOnlyIds) => {
|
|
48
|
-
const accountList = getAccountList(accountState, accountListState, 'accountList');
|
|
49
|
-
const transferEligibleFromApi = transferEligibleIds
|
|
50
|
-
.map((id) => getAccountBaseForTransferAccounts(accountState, id))
|
|
51
|
-
.filter((account) => account != null);
|
|
52
|
-
const coaFallbackAllAccounts = accountList.accounts
|
|
53
|
-
.map((a) => getAccountBase(accountState, a.accountId, 'account_list'))
|
|
54
|
-
.filter((account) => account != null);
|
|
55
|
-
const transferAccountsList = transferEligibleFromApi.length > 0
|
|
56
|
-
? transferEligibleFromApi
|
|
57
|
-
: coaFallbackAllAccounts;
|
|
58
|
-
const creditCardFromApi = creditCardOnlyIds
|
|
59
|
-
.map((id) => getAccountBaseForCreditCardTransferAccounts(accountState, id))
|
|
60
|
-
.filter((account) => account != null);
|
|
61
|
-
const coaFallbackCreditCards = coaFallbackAllAccounts.filter((a) => a.accountType === 'credit_card');
|
|
62
|
-
const creditCardTransferAccountsList = creditCardFromApi.length > 0 ? creditCardFromApi : coaFallbackCreditCards;
|
|
63
|
-
return { creditCardTransferAccountsList, transferAccountsList };
|
|
64
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/** Which pool `fetchAccountsForTransferFlow` / transfer-flow epic should load. */
|
|
2
|
-
export const TRANSFER_ACCOUNTS_FETCH_TYPE = [
|
|
3
|
-
'transferEntryEligible',
|
|
4
|
-
'creditCardOnlyEligible',
|
|
5
|
-
];
|
|
6
|
-
const initialTransferAccountsState = {
|
|
7
|
-
accountIds: [],
|
|
8
|
-
fetchState: 'Not-Started',
|
|
9
|
-
};
|
|
10
|
-
export const initialCreateTransferEntryState = {
|
|
11
|
-
createTransferEntryStatus: 'Not-Started',
|
|
12
|
-
lastTransferEntryReplacement: undefined,
|
|
13
|
-
transferAccountsByType: {
|
|
14
|
-
transferEntryEligible: initialTransferAccountsState,
|
|
15
|
-
creditCardOnlyEligible: initialTransferAccountsState,
|
|
16
|
-
},
|
|
17
|
-
};
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { concat, from, timer } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
4
|
-
import { toTransactionID } from '../../../entity/transaction/payloadTypes/transactionIDPayload';
|
|
5
|
-
import { removeTransaction, updateTransaction, } from '../../../entity/transaction/transactionReducer';
|
|
6
|
-
import { isSuccessResponse } from '../../../responsePayload';
|
|
7
|
-
import { removeTransactionFromAllTabs } from '../../expenseAutomationView/reducers/transactionsViewReducer';
|
|
8
|
-
import { initializeTransactionDetailLocalData, removeTransactionDetail, } from '../../transactionDetail/transactionDetailReducer';
|
|
9
|
-
import { getTransactionDetailKey } from '../../transactionDetail/transactionDetailState';
|
|
10
|
-
import { clearTransferEntryRouteReplacement, createTransferEntry, createTransferEntryFailure, createTransferEntryReplacedTransaction, createTransferEntrySuccess, resetCreateTransferEntryStatus, } from '../createTransferEntryReducer';
|
|
11
|
-
// ─── Pure helpers ────────────────────────────────────────────────────────────
|
|
12
|
-
function transactionIdsAreEqual(a, b) {
|
|
13
|
-
return a.id === b.id && a.type === b.type;
|
|
14
|
-
}
|
|
15
|
-
const successSnackbar = () => openSnackbar({
|
|
16
|
-
messageSection: 'create_transfer_entry',
|
|
17
|
-
messageText: 'success',
|
|
18
|
-
type: 'success',
|
|
19
|
-
});
|
|
20
|
-
const failureSnackbar = () => openSnackbar({
|
|
21
|
-
messageSection: 'create_transfer_entry',
|
|
22
|
-
messageText: 'failed',
|
|
23
|
-
type: 'error',
|
|
24
|
-
});
|
|
25
|
-
function buildFailureActions() {
|
|
26
|
-
return [createTransferEntryFailure(), failureSnackbar()];
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Defensive guard: a BE response that returns 200 with `transaction != null`
|
|
30
|
-
* but where the body lacks a usable id/type is unsafe to seed into the store —
|
|
31
|
-
* downstream code would store under a garbage key and the host hook would try
|
|
32
|
-
* to navigate to a broken url. Treat that case as failure so the source row
|
|
33
|
-
* stays visible and the user can retry.
|
|
34
|
-
*/
|
|
35
|
-
function isWellFormedTransactionPayload(t) {
|
|
36
|
-
return (t != null &&
|
|
37
|
-
typeof t.transaction_id === 'string' &&
|
|
38
|
-
t.transaction_id !== '' &&
|
|
39
|
-
typeof t.transaction_type === 'string' &&
|
|
40
|
-
t.transaction_type !== '');
|
|
41
|
-
}
|
|
42
|
-
function buildSuccessSideEffects(sourceTransactionId) {
|
|
43
|
-
return [
|
|
44
|
-
createTransferEntrySuccess(),
|
|
45
|
-
removeTransactionFromAllTabs(sourceTransactionId),
|
|
46
|
-
successSnackbar(),
|
|
47
|
-
];
|
|
48
|
-
}
|
|
49
|
-
function buildPreviousTransactionCleanupActions(previousTransactionId) {
|
|
50
|
-
return [
|
|
51
|
-
removeTransaction(getTransactionDetailKey(previousTransactionId)),
|
|
52
|
-
removeTransactionDetail(previousTransactionId),
|
|
53
|
-
clearTransferEntryRouteReplacement(),
|
|
54
|
-
];
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Emits `resetCreateTransferEntryStatus()` (and, on the replacement path, the
|
|
58
|
-
* follow-up cleanup actions) one scheduler tick after the success actions.
|
|
59
|
-
*
|
|
60
|
-
* Why the `timer(0)` (and not synchronous emission):
|
|
61
|
-
* On the replacement path the host (web-app-ui) watches
|
|
62
|
-
* `lastTransferEntryReplacement`, navigates to the new transaction url, and
|
|
63
|
-
* then sees `clearTransferEntryRouteReplacement` clear the signal. If we
|
|
64
|
-
* dispatched the cleanup actions in the same tick as
|
|
65
|
-
* `createTransferEntryReplacedTransaction`, redux subscribers would observe
|
|
66
|
-
* `lastTransferEntryReplacement` flicker on then off in a single render, and
|
|
67
|
-
* the old transaction's state (which the still-mounted detail view may be
|
|
68
|
-
* reading) would be torn down before the host has had a chance to start
|
|
69
|
-
* navigating. Deferring by one microtask gives the host exactly one render
|
|
70
|
-
* pass to react before we tear down the previous transaction.
|
|
71
|
-
*/
|
|
72
|
-
function delayedResetAndPreviousCleanup(previousTransactionId) {
|
|
73
|
-
return timer(0).pipe(mergeMap(() => {
|
|
74
|
-
const actions = [resetCreateTransferEntryStatus()];
|
|
75
|
-
if (previousTransactionId != null) {
|
|
76
|
-
actions.push(...buildPreviousTransactionCleanupActions(previousTransactionId));
|
|
77
|
-
}
|
|
78
|
-
return from(actions);
|
|
79
|
-
}));
|
|
80
|
-
}
|
|
81
|
-
// ─── Success-path branches ───────────────────────────────────────────────────
|
|
82
|
-
function handleSuccessWithoutTransactionBody(transactionId) {
|
|
83
|
-
return concat(from(buildSuccessSideEffects(transactionId)), delayedResetAndPreviousCleanup(undefined));
|
|
84
|
-
}
|
|
85
|
-
function handleSuccessWithTransactionBody(transactionPayload, vendorPayload, previousTransactionId, sourceTransactionId) {
|
|
86
|
-
const newTransactionId = toTransactionID(transactionPayload);
|
|
87
|
-
const replaced = !transactionIdsAreEqual(previousTransactionId, newTransactionId);
|
|
88
|
-
const immediate = [
|
|
89
|
-
updateTransaction(getTransactionDetailKey(newTransactionId), transactionPayload),
|
|
90
|
-
initializeTransactionDetailLocalData({
|
|
91
|
-
transactionId: newTransactionId,
|
|
92
|
-
vendorId: vendorPayload?.[0]?.vendor_id,
|
|
93
|
-
}),
|
|
94
|
-
...buildSuccessSideEffects(sourceTransactionId),
|
|
95
|
-
];
|
|
96
|
-
if (replaced) {
|
|
97
|
-
immediate.push(createTransferEntryReplacedTransaction(previousTransactionId, newTransactionId));
|
|
98
|
-
}
|
|
99
|
-
return concat(from(immediate), delayedResetAndPreviousCleanup(replaced ? previousTransactionId : undefined));
|
|
100
|
-
}
|
|
101
|
-
// ─── Top-level epic ──────────────────────────────────────────────────────────
|
|
102
|
-
const CREATE_TRANSFER_ENTRY_URL = `https://dev.api.zeni.ai/version/accounting/komal/1.0/transactions/transaction-type-update`;
|
|
103
|
-
export const createTransferEntryEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(createTransferEntry.match), mergeMap((action) => {
|
|
104
|
-
const { transactionId, creditAccountIntegrationId, debitAccountIntegrationId, memo, transactionType, sourceTransactionType, } = action.payload;
|
|
105
|
-
const previousTransactionId = {
|
|
106
|
-
id: transactionId,
|
|
107
|
-
type: sourceTransactionType,
|
|
108
|
-
};
|
|
109
|
-
return zeniAPI
|
|
110
|
-
.postAndGetJSON(CREATE_TRANSFER_ENTRY_URL, {
|
|
111
|
-
transaction_type: transactionType,
|
|
112
|
-
transaction_id: transactionId,
|
|
113
|
-
to_account_integration_id: creditAccountIntegrationId,
|
|
114
|
-
from_account_integration_id: debitAccountIntegrationId,
|
|
115
|
-
memo,
|
|
116
|
-
})
|
|
117
|
-
.pipe(mergeMap((response) => {
|
|
118
|
-
if (!isSuccessResponse(response)) {
|
|
119
|
-
return from(buildFailureActions());
|
|
120
|
-
}
|
|
121
|
-
const transaction = response.data?.transaction;
|
|
122
|
-
if (transaction != null) {
|
|
123
|
-
if (!isWellFormedTransactionPayload(transaction)) {
|
|
124
|
-
return from(buildFailureActions());
|
|
125
|
-
}
|
|
126
|
-
return handleSuccessWithTransactionBody(transaction, response.data?.vendors, previousTransactionId, transactionId);
|
|
127
|
-
}
|
|
128
|
-
return handleSuccessWithoutTransactionBody(transactionId);
|
|
129
|
-
}), catchError(() => from(buildFailureActions())));
|
|
130
|
-
}));
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
-
import { updateAccounts } from '../../../entity/account/accountReducer';
|
|
4
|
-
import { isSuccessResponse } from '../../../responsePayload';
|
|
5
|
-
import { fetchAccountsForTransferFlow, updateAccountsForTransferFlow, updateAccountsForTransferFlowFailure, } from '../createTransferEntryReducer';
|
|
6
|
-
const REPORT_ID_BY_TYPE = {
|
|
7
|
-
transferEntryEligible: 'transfer_accounts',
|
|
8
|
-
creditCardOnlyEligible: 'credit_card_transfer_accounts',
|
|
9
|
-
};
|
|
10
|
-
const QUERY_BY_TYPE = {
|
|
11
|
-
transferEntryEligible: { is_only_include_transfer_accounts: true },
|
|
12
|
-
creditCardOnlyEligible: { is_include_only_credit_card_accounts: true },
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Pools fetched concurrently: `groupBy(kind)` keeps `transferEntryEligible`
|
|
16
|
-
* and `creditCardOnlyEligible` in their own streams so a back-to-back dispatch
|
|
17
|
-
* of both does not cancel the first. Within a single type, a fresh dispatch
|
|
18
|
-
* supersedes any in-flight request (per-group `switchMap`).
|
|
19
|
-
*/
|
|
20
|
-
export const fetchTransferAccountsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchAccountsForTransferFlow.match), groupBy((action) => action.payload.kind), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
21
|
-
const { kind } = action.payload;
|
|
22
|
-
const queryValue = QUERY_BY_TYPE[kind];
|
|
23
|
-
const reportId = REPORT_ID_BY_TYPE[kind];
|
|
24
|
-
const url = `https://dev.api.zeni.ai/version/accounting/komal/1.0/accounts?query=${encodeURIComponent(JSON.stringify(queryValue))}`;
|
|
25
|
-
return zeniAPI.getJSON(url).pipe(mergeMap((response) => {
|
|
26
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
27
|
-
const accountIds = response.data.accounts.map((account) => account.account_id);
|
|
28
|
-
const actions = [
|
|
29
|
-
updateAccounts(response.data.accounts, reportId),
|
|
30
|
-
updateAccountsForTransferFlow({ accountIds, kind }),
|
|
31
|
-
];
|
|
32
|
-
return of(...actions);
|
|
33
|
-
}
|
|
34
|
-
return of(updateAccountsForTransferFlowFailure({ kind }));
|
|
35
|
-
}), catchError(() => of(updateAccountsForTransferFlowFailure({ kind }))));
|
|
36
|
-
}))));
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ID } from '../../commonStateTypes/common';
|
|
2
|
-
import { TransactionID } from '../../entity/transaction/stateTypes/transaction';
|
|
3
|
-
import { TransactionType } from '../../entity/transaction/stateTypes/transactionType';
|
|
4
|
-
import { CreateTransferEntryState, TransferAccountsFetchType } from './createTransferEntryState';
|
|
5
|
-
export declare const initialState: CreateTransferEntryState;
|
|
6
|
-
export declare const fetchAccountsForTransferFlow: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
7
|
-
kind: TransferAccountsFetchType;
|
|
8
|
-
}, "createTransferEntry/fetchAccountsForTransferFlow">, updateAccountsForTransferFlow: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
9
|
-
accountIds: ID[];
|
|
10
|
-
kind: TransferAccountsFetchType;
|
|
11
|
-
}, "createTransferEntry/updateAccountsForTransferFlow">, updateAccountsForTransferFlowFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
12
|
-
kind: TransferAccountsFetchType;
|
|
13
|
-
}, "createTransferEntry/updateAccountsForTransferFlowFailure">, createTransferEntry: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: {
|
|
14
|
-
creditAccountIntegrationId: string;
|
|
15
|
-
debitAccountIntegrationId: string;
|
|
16
|
-
memo: string;
|
|
17
|
-
sourceTransactionType: TransactionType;
|
|
18
|
-
transactionId: ID;
|
|
19
|
-
transactionType: TransactionType;
|
|
20
|
-
}], {
|
|
21
|
-
creditAccountIntegrationId: string;
|
|
22
|
-
debitAccountIntegrationId: string;
|
|
23
|
-
memo: string;
|
|
24
|
-
sourceTransactionType: TransactionType;
|
|
25
|
-
transactionId: ID;
|
|
26
|
-
transactionType: TransactionType;
|
|
27
|
-
}, "createTransferEntry/createTransferEntry", never, never>, createTransferEntrySuccess: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"createTransferEntry/createTransferEntrySuccess">, createTransferEntryFailure: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"createTransferEntry/createTransferEntryFailure">, resetCreateTransferEntryStatus: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"createTransferEntry/resetCreateTransferEntryStatus">, createTransferEntryReplacedTransaction: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[previousTransactionId: TransactionID, newTransactionId: TransactionID], {
|
|
28
|
-
newTransactionId: TransactionID;
|
|
29
|
-
previousTransactionId: TransactionID;
|
|
30
|
-
}, "createTransferEntry/createTransferEntryReplacedTransaction", never, never>, clearTransferEntryRouteReplacement: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"createTransferEntry/clearTransferEntryRouteReplacement">, clearCreateTransferEntry: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"createTransferEntry/clearCreateTransferEntry">;
|
|
31
|
-
declare const _default: import("redux").Reducer<CreateTransferEntryState>;
|
|
32
|
-
export default _default;
|