@zeniai/client-epic-state 5.3.19 → 5.3.21-beta0KB

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 (99) hide show
  1. package/lib/commonStateTypes/coaBalance/coaBalance.d.ts +9 -0
  2. package/lib/commonStateTypes/coaBalance/coaBalance.js +11 -0
  3. package/lib/entity/genericEntity/customerWithSubCustomersId.d.ts +7 -0
  4. package/lib/entity/genericEntity/customerWithSubCustomersId.js +17 -0
  5. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  6. package/lib/entity/snackbar/snackbarTypes.js +1 -0
  7. package/lib/entity/tenant/epic/fetchAllTenantsEpic.js +6 -4
  8. package/lib/entity/tenant/tenantPayload.d.ts +6 -0
  9. package/lib/entity/tenant/tenantPayload.js +5 -0
  10. package/lib/entity/tenant/tenantReducer.d.ts +6 -2
  11. package/lib/entity/tenant/tenantReducer.js +32 -5
  12. package/lib/entity/tenant/tenantSelector.d.ts +2 -1
  13. package/lib/entity/tenant/tenantSelector.js +4 -1
  14. package/lib/entity/tenant/tenantState.d.ts +10 -0
  15. package/lib/entity/tenant/tenantState.js +5 -0
  16. package/lib/epic.d.ts +2 -1
  17. package/lib/epic.js +3 -0
  18. package/lib/esm/commonStateTypes/coaBalance/coaBalance.js +10 -0
  19. package/lib/esm/entity/genericEntity/customerWithSubCustomersId.js +12 -0
  20. package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
  21. package/lib/esm/entity/tenant/epic/fetchAllTenantsEpic.js +6 -4
  22. package/lib/esm/entity/tenant/tenantPayload.js +4 -1
  23. package/lib/esm/entity/tenant/tenantReducer.js +31 -4
  24. package/lib/esm/entity/tenant/tenantSelector.js +2 -0
  25. package/lib/esm/entity/tenant/tenantState.js +4 -1
  26. package/lib/esm/epic.js +4 -1
  27. package/lib/esm/index.js +7 -6
  28. package/lib/esm/view/balanceSheet/balanceSheetForTimeframeEpic.js +9 -4
  29. package/lib/esm/view/balanceSheet/balanceSheetReducer.js +2 -0
  30. package/lib/esm/view/cashFlow/cashFlowForTimeframeEpic.js +11 -5
  31. package/lib/esm/view/cashFlow/cashFlowReducer.js +2 -0
  32. package/lib/esm/view/companyView/companyViewReducer.js +26 -1
  33. package/lib/esm/view/companyView/epic/companyPassport/updateCustomersTabSettingEpic.js +47 -0
  34. package/lib/esm/view/companyView/selector/companyPassportViewSelector.js +2 -0
  35. package/lib/esm/view/companyView/types/companyPassport/companyPassportViewState.js +4 -0
  36. package/lib/esm/view/customerSummaryView/customerSummaryViewReducer.js +39 -6
  37. package/lib/esm/view/customerSummaryView/customerSummaryViewSelector.js +41 -11
  38. package/lib/esm/view/customerSummaryView/epic/fetchCustomerSummaryListEpic.js +6 -1
  39. package/lib/esm/view/financeStatement/financeStatementSelector.js +18 -0
  40. package/lib/esm/view/profitAndLoss/profitAndLossForTimeframeEpic.js +9 -4
  41. package/lib/esm/view/profitAndLoss/profitAndLossReducer.js +5 -1
  42. package/lib/esm/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +23 -3
  43. package/lib/esm/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +17 -4
  44. package/lib/esm/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
  45. package/lib/esm/view/transactionDetail/createTransaction/epics/createTransactionEpic.js +1 -5
  46. package/lib/esm/view/transactionList/fetchTransactionListByEntityEpic.js +11 -2
  47. package/lib/esm/view/transactionList/filterTransactionsByTimePeriod.js +18 -0
  48. package/lib/esm/view/transactionList/transactionListByAccountSelector.js +2 -1
  49. package/lib/esm/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
  50. package/lib/esm/view/transactionList/transactionListByClassSelector.js +2 -1
  51. package/lib/esm/view/transactionList/transactionListByProjectSelector.js +2 -1
  52. package/lib/esm/view/transactionList/transactionListReducer.js +24 -15
  53. package/lib/esm/view/trend/fetchIncomeTrendEpic.js +6 -2
  54. package/lib/index.d.ts +9 -8
  55. package/lib/index.js +53 -46
  56. package/lib/view/balanceSheet/balanceSheetForTimeframeEpic.js +8 -3
  57. package/lib/view/balanceSheet/balanceSheetReducer.js +2 -0
  58. package/lib/view/balanceSheet/balanceSheetState.d.ts +2 -0
  59. package/lib/view/cashFlow/cashFlowForTimeframeEpic.js +10 -4
  60. package/lib/view/cashFlow/cashFlowReducer.js +2 -0
  61. package/lib/view/cashFlow/cashFlowState.d.ts +2 -0
  62. package/lib/view/companyView/companyViewReducer.d.ts +8 -1
  63. package/lib/view/companyView/companyViewReducer.js +28 -3
  64. package/lib/view/companyView/epic/companyPassport/updateCustomersTabSettingEpic.d.ts +11 -0
  65. package/lib/view/companyView/epic/companyPassport/updateCustomersTabSettingEpic.js +51 -0
  66. package/lib/view/companyView/selector/companyPassportViewSelector.d.ts +1 -0
  67. package/lib/view/companyView/selector/companyPassportViewSelector.js +4 -1
  68. package/lib/view/companyView/types/companyPassport/companyPassportViewState.d.ts +1 -0
  69. package/lib/view/companyView/types/companyPassport/companyPassportViewState.js +4 -0
  70. package/lib/view/customerSummaryView/customerSummaryViewPayload.d.ts +20 -1
  71. package/lib/view/customerSummaryView/customerSummaryViewReducer.d.ts +3 -1
  72. package/lib/view/customerSummaryView/customerSummaryViewReducer.js +42 -6
  73. package/lib/view/customerSummaryView/customerSummaryViewSelector.d.ts +13 -1
  74. package/lib/view/customerSummaryView/customerSummaryViewSelector.js +45 -12
  75. package/lib/view/customerSummaryView/customerSummaryViewState.d.ts +24 -10
  76. package/lib/view/customerSummaryView/epic/fetchCustomerSummaryListEpic.js +6 -1
  77. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  78. package/lib/view/financeStatement/financeStatementSelector.d.ts +8 -0
  79. package/lib/view/financeStatement/financeStatementSelector.js +18 -0
  80. package/lib/view/profitAndLoss/profitAndLossForTimeframeEpic.js +8 -3
  81. package/lib/view/profitAndLoss/profitAndLossReducer.js +5 -1
  82. package/lib/view/profitAndLoss/profitAndLossState.d.ts +2 -1
  83. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.d.ts +7 -2
  84. package/lib/view/spendManagement/reimbursement/editRemiView/editRemiViewReducer.js +24 -4
  85. package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.d.ts +7 -4
  86. package/lib/view/spendManagement/reimbursement/editRemiView/epics/fetchRemiAndInitializeLocalStoreEpic.js +15 -1
  87. package/lib/view/spendManagement/reimbursement/remiDetailView/epics/fetchRemiDetailEpic.js +1 -1
  88. package/lib/view/transactionDetail/createTransaction/epics/createTransactionEpic.js +1 -5
  89. package/lib/view/transactionList/fetchTransactionListByEntityEpic.js +11 -2
  90. package/lib/view/transactionList/filterTransactionsByTimePeriod.d.ts +15 -0
  91. package/lib/view/transactionList/filterTransactionsByTimePeriod.js +22 -0
  92. package/lib/view/transactionList/transactionListByAccountSelector.js +2 -1
  93. package/lib/view/transactionList/transactionListByCategoryTypeSelector.js +2 -1
  94. package/lib/view/transactionList/transactionListByClassSelector.js +2 -1
  95. package/lib/view/transactionList/transactionListByProjectSelector.js +2 -1
  96. package/lib/view/transactionList/transactionListReducer.d.ts +3 -1
  97. package/lib/view/transactionList/transactionListReducer.js +24 -15
  98. package/lib/view/trend/fetchIncomeTrendEpic.js +6 -2
  99. package/package.json +1 -1
@@ -9,7 +9,11 @@ const cashFlowPayload_1 = require("./cashFlowPayload");
9
9
  const cashFlowReducer_1 = require("./cashFlowReducer");
10
10
  const reportIdUniqueKey = () => 'cash_flow';
11
11
  exports.reportIdUniqueKey = reportIdUniqueKey;
12
- const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(cashFlowReducer_1.fetchCashFlowForTimeframe.match), (0, operators_1.mergeMap)((action) => {
12
+ const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(cashFlowReducer_1.fetchCashFlowForTimeframe.match),
13
+ // One stream per timeframe: a newer request for the same timeframe (e.g. a
14
+ // custom-date-range change, or a dated fetch right after a default one)
15
+ // cancels the older in-flight request so a stale response can't land last.
16
+ (0, operators_1.groupBy)((action) => action.payload.timeframe), (0, operators_1.mergeMap)((group$) => group$.pipe((0, operators_1.switchMap)((action) => {
13
17
  const getTimeSeriesGroup = (timeframe) => {
14
18
  switch (timeframe) {
15
19
  case 'month':
@@ -24,7 +28,8 @@ const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0
24
28
  is_full_response: action.payload.fetchFullReport,
25
29
  time_series_groups: [getTimeSeriesGroup(action.payload.timeframe)],
26
30
  };
27
- if (action.payload.startDate != null && action.payload.endDate != null) {
31
+ if (action.payload.startDate != null &&
32
+ action.payload.endDate != null) {
28
33
  queryValue.custom_start_date = action.payload.startDate;
29
34
  queryValue.custom_end_date = action.payload.endDate;
30
35
  }
@@ -52,6 +57,7 @@ const fetchCashFlowForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0
52
57
  else {
53
58
  return (0, rxjs_1.of)((0, cashFlowReducer_1.updateCashFlowForTimeframeFailure)(response.status, action.payload.timeframe));
54
59
  }
55
- }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, cashFlowReducer_1.updateCashFlowForTimeframeFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Cash Flow REST API call errored out' + JSON.stringify(error)), action.payload.timeframe))));
56
- }));
60
+ }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, cashFlowReducer_1.updateCashFlowForTimeframeFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Cash Flow REST API call errored out' +
61
+ JSON.stringify(error)), action.payload.timeframe))));
62
+ }))));
57
63
  exports.fetchCashFlowForTimeframeEpic = fetchCashFlowForTimeframeEpic;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.resetCashFlowNodeCollapseState = exports.updateCashFlowUIState = exports.updateCashFlowForTimeframeFailure = exports.updateCashFlowForTimeframe = exports.fetchCashFlowForTimeframe = exports.fetchCashFlow = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const viewAndReportPayloadv2_1 = require("../../commonPayloadTypes/v2/viewAndReportPayloadv2");
7
+ const coaBalance_1 = require("../../commonStateTypes/coaBalance/coaBalance");
7
8
  const rootActions_1 = require("../../rootActions");
8
9
  exports.initialState = {
9
10
  fetchState: {
@@ -58,6 +59,7 @@ const cashFlow = (0, toolkit_1.createSlice)({
58
59
  fetchState: 'In-Progress',
59
60
  error: undefined,
60
61
  };
62
+ draft.customDateRangeByTimeframe = (0, coaBalance_1.withFetchedCustomDateRange)(draft.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate);
61
63
  },
62
64
  },
63
65
  updateCashFlowForTimeframe(draft, action) {
@@ -1,3 +1,4 @@
1
+ import { CustomDateRangeByTimeframe } from '../../commonStateTypes/coaBalance/coaBalance';
1
2
  import { ID } from '../../commonStateTypes/common';
2
3
  import { FetchStateAndError } from '../../commonStateTypes/common';
3
4
  import { Report } from '../../commonStateTypes/viewAndReport/viewAndReport';
@@ -8,6 +9,7 @@ export interface CashFlowState extends Report {
8
9
  year: FetchStateAndError;
9
10
  };
10
11
  uiState: CashFlowUIState;
12
+ customDateRangeByTimeframe?: CustomDateRangeByTimeframe;
11
13
  }
12
14
  export interface CashFlowUIState {
13
15
  nodeCollapseState: Record<ID, boolean>;
@@ -78,7 +78,14 @@ export declare const fetchCompanyPassportView: import("@reduxjs/toolkit").Action
78
78
  enabled: boolean;
79
79
  }, "companyView/updateAutoReviewIncomeWithoutCustomer", never, never>, updateAutoReviewIncomeWithoutCustomerSuccess: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"companyView/updateAutoReviewIncomeWithoutCustomerSuccess">, updateAutoReviewIncomeWithoutCustomerFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
80
80
  status: ZeniAPIStatus;
81
- }, "companyView/updateAutoReviewIncomeWithoutCustomerFailure">, updateCompanyProductServices: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[companyId: string, services: CompanyProductServicesInput], {
81
+ }, "companyView/updateAutoReviewIncomeWithoutCustomerFailure">, updateCustomersTabSetting: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[companyId: string, setting: keyof import("../../entity/tenant/tenantState").CustomersTabSettings, enabled: boolean, tenantId: string], {
82
+ companyId: string;
83
+ enabled: boolean;
84
+ setting: keyof import("../../entity/tenant/tenantState").CustomersTabSettings;
85
+ tenantId: string;
86
+ }, "companyView/updateCustomersTabSetting", never, never>, updateCustomersTabSettingSuccess: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"companyView/updateCustomersTabSettingSuccess">, updateCustomersTabSettingFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
87
+ status: ZeniAPIStatus;
88
+ }, "companyView/updateCustomersTabSettingFailure">, updateCompanyProductServices: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[companyId: string, services: CompanyProductServicesInput], {
82
89
  companyId: string;
83
90
  services: CompanyProductServicesInput;
84
91
  }, "companyView/updateCompanyProductServices", never, never>, updateCompanyProductServicesSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.dismissCapitalizationOnboarding = exports.updateCapitalizationAccountThresholdFailure = exports.updateCapitalizationAccountThresholdSuccess = exports.updateCapitalizationAccountThreshold = exports.clearQboProjectsReconnectRequest = exports.requestQboProjectsReconnect = exports.updateAccountingProjectsEnabledFailure = exports.updateAccountingProjectsEnabledSuccess = exports.disableAccountingProjects = exports.resumeEnableAccountingProjects = exports.enableAccountingProjects = exports.updateCompanyQboRealmIdFailure = exports.updateCompanyQboRealmIdSuccess = exports.updateCompanyQboRealmId = exports.updateCompanyProductServicesFailure = exports.updateCompanyProductServicesSuccess = exports.updateCompanyProductServices = exports.updateAutoReviewIncomeWithoutCustomerFailure = exports.updateAutoReviewIncomeWithoutCustomerSuccess = exports.updateAutoReviewIncomeWithoutCustomer = exports.updateAccountingClassesEnabledFailure = exports.updateAccountingClassesEnabledSuccess = exports.updateAccountingClassesEnabled = exports.companyPassportUpdateCompanyDetailsFailure = exports.companyPassportUpdateCompanyDetailsSuccess = exports.companyPassportUpdateCompanyDetails = exports.companyPassportClearDataInLocalStore = exports.deleteCompanyOfficerInLocalStore = exports.companyPassportSaveDataInLocalStore = exports.updateCompanyManagementUIState = exports.updateCompanyPortfolioUIState = exports.updateZeniUsersOnFailure = exports.updateZeniUsersOnSuccess = exports.fetchZeniUsers = exports.fetchCompanyPortfolioView = exports.updateCompanyViewOnFailure = exports.updateCompanyViewOnSuccess = exports.companyManagementSaveUpdatesFailure = exports.companyManagementSaveUpdatesSuccess = exports.companyManagementDiscardUpdates = exports.companyManagementSavePendingUpdates = exports.companyManagementSaveUpdates = exports.fetchCompanyManagementView = exports.fetchPortfolioView = exports.fetchSubscriptionView = exports.fetchManagementView = exports.fetchOnboardingView = exports.fetchAllCockpitViews = exports.fetchCompanyPassportView = exports.initialState = void 0;
5
- exports.updateMetaDataOnSendMonthEndReport = exports.updateCompanyMetaDataOnFailure = exports.updateCompanyMetaDataOnSuccess = exports.fetchCompanyMetaData = exports.updateCompanyDownloadState = exports.updateParentSubsidiaryViewOnFailure = exports.updateParentSubsidiaryView = exports.fetchParentSubsidiaryManagementView = exports.saveCompanyPassportDetails = exports.saveIndustryAndIncDateInCompanyPassportLocalStore = exports.updateCompanyPassportLocalStoreData = exports.companyPassportCreateCompanyOfficersFailure = exports.companyPassportCreateCompanyOfficersSuccess = exports.companyPassportCreateCompanyOfficers = exports.companyPassportUpdateCompanyOfficerFailure = exports.companyPassportUpdateCompanyOfficerSuccess = exports.companyPassportUpdateCompanyOfficer = exports.companyPassportUpdatePrimaryContactFailure = exports.companyPassportUpdatePrimaryContactSuccess = exports.companyPassportUpdatePrimaryContact = void 0;
4
+ exports.updateCapitalizationAccountThreshold = exports.clearQboProjectsReconnectRequest = exports.requestQboProjectsReconnect = exports.updateAccountingProjectsEnabledFailure = exports.updateAccountingProjectsEnabledSuccess = exports.disableAccountingProjects = exports.resumeEnableAccountingProjects = exports.enableAccountingProjects = exports.updateCompanyQboRealmIdFailure = exports.updateCompanyQboRealmIdSuccess = exports.updateCompanyQboRealmId = exports.updateCompanyProductServicesFailure = exports.updateCompanyProductServicesSuccess = exports.updateCompanyProductServices = exports.updateCustomersTabSettingFailure = exports.updateCustomersTabSettingSuccess = exports.updateCustomersTabSetting = exports.updateAutoReviewIncomeWithoutCustomerFailure = exports.updateAutoReviewIncomeWithoutCustomerSuccess = exports.updateAutoReviewIncomeWithoutCustomer = exports.updateAccountingClassesEnabledFailure = exports.updateAccountingClassesEnabledSuccess = exports.updateAccountingClassesEnabled = exports.companyPassportUpdateCompanyDetailsFailure = exports.companyPassportUpdateCompanyDetailsSuccess = exports.companyPassportUpdateCompanyDetails = exports.companyPassportClearDataInLocalStore = exports.deleteCompanyOfficerInLocalStore = exports.companyPassportSaveDataInLocalStore = exports.updateCompanyManagementUIState = exports.updateCompanyPortfolioUIState = exports.updateZeniUsersOnFailure = exports.updateZeniUsersOnSuccess = exports.fetchZeniUsers = exports.fetchCompanyPortfolioView = exports.updateCompanyViewOnFailure = exports.updateCompanyViewOnSuccess = exports.companyManagementSaveUpdatesFailure = exports.companyManagementSaveUpdatesSuccess = exports.companyManagementDiscardUpdates = exports.companyManagementSavePendingUpdates = exports.companyManagementSaveUpdates = exports.fetchCompanyManagementView = exports.fetchPortfolioView = exports.fetchSubscriptionView = exports.fetchManagementView = exports.fetchOnboardingView = exports.fetchAllCockpitViews = exports.fetchCompanyPassportView = exports.initialState = void 0;
5
+ exports.updateMetaDataOnSendMonthEndReport = exports.updateCompanyMetaDataOnFailure = exports.updateCompanyMetaDataOnSuccess = exports.fetchCompanyMetaData = exports.updateCompanyDownloadState = exports.updateParentSubsidiaryViewOnFailure = exports.updateParentSubsidiaryView = exports.fetchParentSubsidiaryManagementView = exports.saveCompanyPassportDetails = exports.saveIndustryAndIncDateInCompanyPassportLocalStore = exports.updateCompanyPassportLocalStoreData = exports.companyPassportCreateCompanyOfficersFailure = exports.companyPassportCreateCompanyOfficersSuccess = exports.companyPassportCreateCompanyOfficers = exports.companyPassportUpdateCompanyOfficerFailure = exports.companyPassportUpdateCompanyOfficerSuccess = exports.companyPassportUpdateCompanyOfficer = exports.companyPassportUpdatePrimaryContactFailure = exports.companyPassportUpdatePrimaryContactSuccess = exports.companyPassportUpdatePrimaryContact = exports.dismissCapitalizationOnboarding = exports.updateCapitalizationAccountThresholdFailure = exports.updateCapitalizationAccountThresholdSuccess = void 0;
6
6
  const toolkit_1 = require("@reduxjs/toolkit");
7
7
  const rootActions_1 = require("../../rootActions");
8
8
  const parentSubsidiaryViewState_1 = require("./parentSubsidiaryView/parentSubsidiaryViewState");
@@ -340,6 +340,31 @@ const companyView = (0, toolkit_1.createSlice)({
340
340
  error: action.payload.status,
341
341
  };
342
342
  },
343
+ updateCustomersTabSetting: {
344
+ reducer(draft,
345
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
346
+ _action) {
347
+ draft.passportView.customersTabSettingsUpdateStatus = {
348
+ fetchState: 'In-Progress',
349
+ error: undefined,
350
+ };
351
+ },
352
+ prepare(companyId, setting, enabled, tenantId) {
353
+ return { payload: { companyId, enabled, setting, tenantId } };
354
+ },
355
+ },
356
+ updateCustomersTabSettingSuccess(draft) {
357
+ draft.passportView.customersTabSettingsUpdateStatus = {
358
+ fetchState: 'Completed',
359
+ error: undefined,
360
+ };
361
+ },
362
+ updateCustomersTabSettingFailure(draft, action) {
363
+ draft.passportView.customersTabSettingsUpdateStatus = {
364
+ fetchState: 'Error',
365
+ error: action.payload.status,
366
+ };
367
+ },
343
368
  enableAccountingProjects: {
344
369
  reducer(draft,
345
370
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -784,5 +809,5 @@ const companyView = (0, toolkit_1.createSlice)({
784
809
  });
785
810
  },
786
811
  });
787
- _a = companyView.actions, exports.fetchCompanyPassportView = _a.fetchCompanyPassportView, exports.fetchAllCockpitViews = _a.fetchAllCockpitViews, exports.fetchOnboardingView = _a.fetchOnboardingView, exports.fetchManagementView = _a.fetchManagementView, exports.fetchSubscriptionView = _a.fetchSubscriptionView, exports.fetchPortfolioView = _a.fetchPortfolioView, exports.fetchCompanyManagementView = _a.fetchCompanyManagementView, exports.companyManagementSaveUpdates = _a.companyManagementSaveUpdates, exports.companyManagementSavePendingUpdates = _a.companyManagementSavePendingUpdates, exports.companyManagementDiscardUpdates = _a.companyManagementDiscardUpdates, exports.companyManagementSaveUpdatesSuccess = _a.companyManagementSaveUpdatesSuccess, exports.companyManagementSaveUpdatesFailure = _a.companyManagementSaveUpdatesFailure, exports.updateCompanyViewOnSuccess = _a.updateCompanyViewOnSuccess, exports.updateCompanyViewOnFailure = _a.updateCompanyViewOnFailure, exports.fetchCompanyPortfolioView = _a.fetchCompanyPortfolioView, exports.fetchZeniUsers = _a.fetchZeniUsers, exports.updateZeniUsersOnSuccess = _a.updateZeniUsersOnSuccess, exports.updateZeniUsersOnFailure = _a.updateZeniUsersOnFailure, exports.updateCompanyPortfolioUIState = _a.updateCompanyPortfolioUIState, exports.updateCompanyManagementUIState = _a.updateCompanyManagementUIState, exports.companyPassportSaveDataInLocalStore = _a.companyPassportSaveDataInLocalStore, exports.deleteCompanyOfficerInLocalStore = _a.deleteCompanyOfficerInLocalStore, exports.companyPassportClearDataInLocalStore = _a.companyPassportClearDataInLocalStore, exports.companyPassportUpdateCompanyDetails = _a.companyPassportUpdateCompanyDetails, exports.companyPassportUpdateCompanyDetailsSuccess = _a.companyPassportUpdateCompanyDetailsSuccess, exports.companyPassportUpdateCompanyDetailsFailure = _a.companyPassportUpdateCompanyDetailsFailure, exports.updateAccountingClassesEnabled = _a.updateAccountingClassesEnabled, exports.updateAccountingClassesEnabledSuccess = _a.updateAccountingClassesEnabledSuccess, exports.updateAccountingClassesEnabledFailure = _a.updateAccountingClassesEnabledFailure, exports.updateAutoReviewIncomeWithoutCustomer = _a.updateAutoReviewIncomeWithoutCustomer, exports.updateAutoReviewIncomeWithoutCustomerSuccess = _a.updateAutoReviewIncomeWithoutCustomerSuccess, exports.updateAutoReviewIncomeWithoutCustomerFailure = _a.updateAutoReviewIncomeWithoutCustomerFailure, exports.updateCompanyProductServices = _a.updateCompanyProductServices, exports.updateCompanyProductServicesSuccess = _a.updateCompanyProductServicesSuccess, exports.updateCompanyProductServicesFailure = _a.updateCompanyProductServicesFailure, exports.updateCompanyQboRealmId = _a.updateCompanyQboRealmId, exports.updateCompanyQboRealmIdSuccess = _a.updateCompanyQboRealmIdSuccess, exports.updateCompanyQboRealmIdFailure = _a.updateCompanyQboRealmIdFailure, exports.enableAccountingProjects = _a.enableAccountingProjects, exports.resumeEnableAccountingProjects = _a.resumeEnableAccountingProjects, exports.disableAccountingProjects = _a.disableAccountingProjects, exports.updateAccountingProjectsEnabledSuccess = _a.updateAccountingProjectsEnabledSuccess, exports.updateAccountingProjectsEnabledFailure = _a.updateAccountingProjectsEnabledFailure, exports.requestQboProjectsReconnect = _a.requestQboProjectsReconnect, exports.clearQboProjectsReconnectRequest = _a.clearQboProjectsReconnectRequest, exports.updateCapitalizationAccountThreshold = _a.updateCapitalizationAccountThreshold, exports.updateCapitalizationAccountThresholdSuccess = _a.updateCapitalizationAccountThresholdSuccess, exports.updateCapitalizationAccountThresholdFailure = _a.updateCapitalizationAccountThresholdFailure, exports.dismissCapitalizationOnboarding = _a.dismissCapitalizationOnboarding, exports.companyPassportUpdatePrimaryContact = _a.companyPassportUpdatePrimaryContact, exports.companyPassportUpdatePrimaryContactSuccess = _a.companyPassportUpdatePrimaryContactSuccess, exports.companyPassportUpdatePrimaryContactFailure = _a.companyPassportUpdatePrimaryContactFailure, exports.companyPassportUpdateCompanyOfficer = _a.companyPassportUpdateCompanyOfficer, exports.companyPassportUpdateCompanyOfficerSuccess = _a.companyPassportUpdateCompanyOfficerSuccess, exports.companyPassportUpdateCompanyOfficerFailure = _a.companyPassportUpdateCompanyOfficerFailure, exports.companyPassportCreateCompanyOfficers = _a.companyPassportCreateCompanyOfficers, exports.companyPassportCreateCompanyOfficersSuccess = _a.companyPassportCreateCompanyOfficersSuccess, exports.companyPassportCreateCompanyOfficersFailure = _a.companyPassportCreateCompanyOfficersFailure, exports.updateCompanyPassportLocalStoreData = _a.updateCompanyPassportLocalStoreData, exports.saveIndustryAndIncDateInCompanyPassportLocalStore = _a.saveIndustryAndIncDateInCompanyPassportLocalStore, exports.saveCompanyPassportDetails = _a.saveCompanyPassportDetails, exports.fetchParentSubsidiaryManagementView = _a.fetchParentSubsidiaryManagementView, exports.updateParentSubsidiaryView = _a.updateParentSubsidiaryView, exports.updateParentSubsidiaryViewOnFailure = _a.updateParentSubsidiaryViewOnFailure, exports.updateCompanyDownloadState = _a.updateCompanyDownloadState, exports.fetchCompanyMetaData = _a.fetchCompanyMetaData, exports.updateCompanyMetaDataOnSuccess = _a.updateCompanyMetaDataOnSuccess, exports.updateCompanyMetaDataOnFailure = _a.updateCompanyMetaDataOnFailure, exports.updateMetaDataOnSendMonthEndReport = _a.updateMetaDataOnSendMonthEndReport;
812
+ _a = companyView.actions, exports.fetchCompanyPassportView = _a.fetchCompanyPassportView, exports.fetchAllCockpitViews = _a.fetchAllCockpitViews, exports.fetchOnboardingView = _a.fetchOnboardingView, exports.fetchManagementView = _a.fetchManagementView, exports.fetchSubscriptionView = _a.fetchSubscriptionView, exports.fetchPortfolioView = _a.fetchPortfolioView, exports.fetchCompanyManagementView = _a.fetchCompanyManagementView, exports.companyManagementSaveUpdates = _a.companyManagementSaveUpdates, exports.companyManagementSavePendingUpdates = _a.companyManagementSavePendingUpdates, exports.companyManagementDiscardUpdates = _a.companyManagementDiscardUpdates, exports.companyManagementSaveUpdatesSuccess = _a.companyManagementSaveUpdatesSuccess, exports.companyManagementSaveUpdatesFailure = _a.companyManagementSaveUpdatesFailure, exports.updateCompanyViewOnSuccess = _a.updateCompanyViewOnSuccess, exports.updateCompanyViewOnFailure = _a.updateCompanyViewOnFailure, exports.fetchCompanyPortfolioView = _a.fetchCompanyPortfolioView, exports.fetchZeniUsers = _a.fetchZeniUsers, exports.updateZeniUsersOnSuccess = _a.updateZeniUsersOnSuccess, exports.updateZeniUsersOnFailure = _a.updateZeniUsersOnFailure, exports.updateCompanyPortfolioUIState = _a.updateCompanyPortfolioUIState, exports.updateCompanyManagementUIState = _a.updateCompanyManagementUIState, exports.companyPassportSaveDataInLocalStore = _a.companyPassportSaveDataInLocalStore, exports.deleteCompanyOfficerInLocalStore = _a.deleteCompanyOfficerInLocalStore, exports.companyPassportClearDataInLocalStore = _a.companyPassportClearDataInLocalStore, exports.companyPassportUpdateCompanyDetails = _a.companyPassportUpdateCompanyDetails, exports.companyPassportUpdateCompanyDetailsSuccess = _a.companyPassportUpdateCompanyDetailsSuccess, exports.companyPassportUpdateCompanyDetailsFailure = _a.companyPassportUpdateCompanyDetailsFailure, exports.updateAccountingClassesEnabled = _a.updateAccountingClassesEnabled, exports.updateAccountingClassesEnabledSuccess = _a.updateAccountingClassesEnabledSuccess, exports.updateAccountingClassesEnabledFailure = _a.updateAccountingClassesEnabledFailure, exports.updateAutoReviewIncomeWithoutCustomer = _a.updateAutoReviewIncomeWithoutCustomer, exports.updateAutoReviewIncomeWithoutCustomerSuccess = _a.updateAutoReviewIncomeWithoutCustomerSuccess, exports.updateAutoReviewIncomeWithoutCustomerFailure = _a.updateAutoReviewIncomeWithoutCustomerFailure, exports.updateCustomersTabSetting = _a.updateCustomersTabSetting, exports.updateCustomersTabSettingSuccess = _a.updateCustomersTabSettingSuccess, exports.updateCustomersTabSettingFailure = _a.updateCustomersTabSettingFailure, exports.updateCompanyProductServices = _a.updateCompanyProductServices, exports.updateCompanyProductServicesSuccess = _a.updateCompanyProductServicesSuccess, exports.updateCompanyProductServicesFailure = _a.updateCompanyProductServicesFailure, exports.updateCompanyQboRealmId = _a.updateCompanyQboRealmId, exports.updateCompanyQboRealmIdSuccess = _a.updateCompanyQboRealmIdSuccess, exports.updateCompanyQboRealmIdFailure = _a.updateCompanyQboRealmIdFailure, exports.enableAccountingProjects = _a.enableAccountingProjects, exports.resumeEnableAccountingProjects = _a.resumeEnableAccountingProjects, exports.disableAccountingProjects = _a.disableAccountingProjects, exports.updateAccountingProjectsEnabledSuccess = _a.updateAccountingProjectsEnabledSuccess, exports.updateAccountingProjectsEnabledFailure = _a.updateAccountingProjectsEnabledFailure, exports.requestQboProjectsReconnect = _a.requestQboProjectsReconnect, exports.clearQboProjectsReconnectRequest = _a.clearQboProjectsReconnectRequest, exports.updateCapitalizationAccountThreshold = _a.updateCapitalizationAccountThreshold, exports.updateCapitalizationAccountThresholdSuccess = _a.updateCapitalizationAccountThresholdSuccess, exports.updateCapitalizationAccountThresholdFailure = _a.updateCapitalizationAccountThresholdFailure, exports.dismissCapitalizationOnboarding = _a.dismissCapitalizationOnboarding, exports.companyPassportUpdatePrimaryContact = _a.companyPassportUpdatePrimaryContact, exports.companyPassportUpdatePrimaryContactSuccess = _a.companyPassportUpdatePrimaryContactSuccess, exports.companyPassportUpdatePrimaryContactFailure = _a.companyPassportUpdatePrimaryContactFailure, exports.companyPassportUpdateCompanyOfficer = _a.companyPassportUpdateCompanyOfficer, exports.companyPassportUpdateCompanyOfficerSuccess = _a.companyPassportUpdateCompanyOfficerSuccess, exports.companyPassportUpdateCompanyOfficerFailure = _a.companyPassportUpdateCompanyOfficerFailure, exports.companyPassportCreateCompanyOfficers = _a.companyPassportCreateCompanyOfficers, exports.companyPassportCreateCompanyOfficersSuccess = _a.companyPassportCreateCompanyOfficersSuccess, exports.companyPassportCreateCompanyOfficersFailure = _a.companyPassportCreateCompanyOfficersFailure, exports.updateCompanyPassportLocalStoreData = _a.updateCompanyPassportLocalStoreData, exports.saveIndustryAndIncDateInCompanyPassportLocalStore = _a.saveIndustryAndIncDateInCompanyPassportLocalStore, exports.saveCompanyPassportDetails = _a.saveCompanyPassportDetails, exports.fetchParentSubsidiaryManagementView = _a.fetchParentSubsidiaryManagementView, exports.updateParentSubsidiaryView = _a.updateParentSubsidiaryView, exports.updateParentSubsidiaryViewOnFailure = _a.updateParentSubsidiaryViewOnFailure, exports.updateCompanyDownloadState = _a.updateCompanyDownloadState, exports.fetchCompanyMetaData = _a.fetchCompanyMetaData, exports.updateCompanyMetaDataOnSuccess = _a.updateCompanyMetaDataOnSuccess, exports.updateCompanyMetaDataOnFailure = _a.updateCompanyMetaDataOnFailure, exports.updateMetaDataOnSendMonthEndReport = _a.updateMetaDataOnSendMonthEndReport;
788
813
  exports.default = companyView.reducer;
@@ -0,0 +1,11 @@
1
+ import { ActionsObservable, StateObservable } from 'redux-observable';
2
+ import { Observable } from 'rxjs';
3
+ import { updateCompanies } from '../../../../entity/company/companyReducer';
4
+ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
5
+ import { updateTenantCustomersTabSetting } from '../../../../entity/tenant/tenantReducer';
6
+ import { RootState } from '../../../../rootStateTypes';
7
+ import { ZeniAPI } from '../../../../zeniAPI';
8
+ import { updateCustomersTabSetting, updateCustomersTabSettingFailure, updateCustomersTabSettingSuccess } from '../../companyViewReducer';
9
+ export type ActionType = ReturnType<typeof updateCompanies> | ReturnType<typeof updateTenantCustomersTabSetting> | ReturnType<typeof openSnackbar> | ReturnType<typeof updateCustomersTabSetting> | ReturnType<typeof updateCustomersTabSettingSuccess> | ReturnType<typeof updateCustomersTabSettingFailure>;
10
+ /** Settings › Accounting › Customers: save one Customers tab setting (accounting_config is deep-merged). */
11
+ export declare const updateCustomersTabSettingEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateCustomersTabSettingEpic = void 0;
4
+ const rxjs_1 = require("rxjs");
5
+ const operators_1 = require("rxjs/operators");
6
+ const companyReducer_1 = require("../../../../entity/company/companyReducer");
7
+ const snackbarReducer_1 = require("../../../../entity/snackbar/snackbarReducer");
8
+ const tenantPayload_1 = require("../../../../entity/tenant/tenantPayload");
9
+ const tenantReducer_1 = require("../../../../entity/tenant/tenantReducer");
10
+ const responsePayload_1 = require("../../../../responsePayload");
11
+ const companyViewReducer_1 = require("../../companyViewReducer");
12
+ const failureActions = (status) => [
13
+ (0, companyViewReducer_1.updateCustomersTabSettingFailure)({ status }),
14
+ (0, snackbarReducer_1.openSnackbar)({
15
+ messageSection: 'customers_tab_settings_update',
16
+ messageText: 'failed',
17
+ type: 'error',
18
+ }),
19
+ ];
20
+ /** Settings › Accounting › Customers: save one Customers tab setting (accounting_config is deep-merged). */
21
+ const updateCustomersTabSettingEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(companyViewReducer_1.updateCustomersTabSetting.match),
22
+ // The two settings are separate keys: a quick second toggle mustn't cancel the first save
23
+ (0, operators_1.mergeMap)((action) => {
24
+ const { companyId, enabled, setting, tenantId } = action.payload;
25
+ return zeniAPI
26
+ .putAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/companies/${companyId}`, {
27
+ accounting_config: {
28
+ customers: { [tenantPayload_1.CUSTOMERS_TAB_SETTING_API_KEYS[setting]]: enabled },
29
+ },
30
+ })
31
+ .pipe((0, operators_1.mergeMap)((response) => {
32
+ const companies = response.data?.companies ?? [];
33
+ if (!(0, responsePayload_1.isSuccessResponse)(response) || companies.length === 0) {
34
+ return (0, rxjs_1.from)(failureActions(response.status));
35
+ }
36
+ return (0, rxjs_1.from)([
37
+ (0, companyReducer_1.updateCompanies)({ payload: companies, schema: {} }),
38
+ (0, tenantReducer_1.updateTenantCustomersTabSetting)({ enabled, setting, tenantId }),
39
+ (0, companyViewReducer_1.updateCustomersTabSettingSuccess)(),
40
+ (0, snackbarReducer_1.openSnackbar)({
41
+ messageSection: 'customers_tab_settings_update',
42
+ messageText: 'success',
43
+ type: 'success',
44
+ }),
45
+ ]);
46
+ }), (0, operators_1.catchError)((error) => (0, rxjs_1.from)(failureActions((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Update Customers tab setting errored out: ' +
47
+ (error instanceof Error
48
+ ? error.message
49
+ : JSON.stringify(error)))))));
50
+ }));
51
+ exports.updateCustomersTabSettingEpic = updateCustomersTabSettingEpic;
@@ -34,3 +34,4 @@ export interface CompanyPassportLocalStoreDataView {
34
34
  export declare const getCompanyPassportView: (state: RootState) => CompanyPassportView;
35
35
  export declare function getCompanyPassportLocalStoreData(state: RootState): CompanyPassportLocalStoreDataView;
36
36
  export declare const isCompanyPassportDataToBeSaved: (companyLocalStoreData: CompanyPassportLocalStoreDataView, companyView: CompanyView, companyFiles: File[]) => boolean;
37
+ export declare const getIsCustomersTabSettingsUpdateInProgress: (state: RootState) => boolean;
@@ -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.isCompanyPassportDataToBeSaved = exports.getCompanyPassportView = void 0;
6
+ exports.getIsCustomersTabSettingsUpdateInProgress = exports.isCompanyPassportDataToBeSaved = exports.getCompanyPassportView = void 0;
7
7
  exports.getCompanyPassportLocalStoreData = getCompanyPassportLocalStoreData;
8
8
  const toolkit_1 = require("@reduxjs/toolkit");
9
9
  const get_1 = __importDefault(require("lodash/get"));
@@ -161,3 +161,6 @@ const isCompanyPassportDataToBeSaved = (companyLocalStoreData, companyView, comp
161
161
  return isCompanyDataUpdated;
162
162
  };
163
163
  exports.isCompanyPassportDataToBeSaved = isCompanyPassportDataToBeSaved;
164
+ const getIsCustomersTabSettingsUpdateInProgress = (state) => state.companyViewState.passportView.customersTabSettingsUpdateStatus
165
+ .fetchState === 'In-Progress';
166
+ exports.getIsCustomersTabSettingsUpdateInProgress = getIsCustomersTabSettingsUpdateInProgress;
@@ -16,6 +16,7 @@ export interface CompanyPassportViewState extends CommonState, FetchedState {
16
16
  updateStatus: FetchStateAndError;
17
17
  localData?: CompanyOfficerLocalData;
18
18
  }>;
19
+ customersTabSettingsUpdateStatus: FetchStateAndError;
19
20
  needsQboProjectsReconnect: boolean;
20
21
  primaryContact: {
21
22
  updateStatus: FetchStateAndError;
@@ -20,6 +20,10 @@ exports.initialCompanyPassportView = {
20
20
  fetchState: 'Not-Started',
21
21
  error: undefined,
22
22
  },
23
+ customersTabSettingsUpdateStatus: {
24
+ fetchState: 'Not-Started',
25
+ error: undefined,
26
+ },
23
27
  needsQboProjectsReconnect: false,
24
28
  companyDetails: {
25
29
  localData: undefined,
@@ -1,4 +1,5 @@
1
1
  import { ZeniAPIResponse } from '../../responsePayload';
2
+ import { CustomerRevenueKey } from './customerSummaryViewState';
2
3
  export interface CustomerSummaryRevenuePayload {
3
4
  last_3_months_revenue?: number;
4
5
  last_6_months_revenue?: number;
@@ -9,7 +10,17 @@ export interface CustomerSummaryRevenuePayload {
9
10
  previous_year_revenue?: number;
10
11
  year_to_date_revenue?: number;
11
12
  }
12
- export interface CustomerSummaryPayload extends CustomerSummaryRevenuePayload {
13
+ interface CustomerSummaryReferencePayload {
14
+ customer_id: string;
15
+ customer_name?: string;
16
+ }
17
+ /** Details: the figures over the customer and its active sub-customers and projects. */
18
+ export type CustomerSummaryTotalsPayload = {
19
+ [Key in CustomerRevenueKey as `total_${Key}`]?: number;
20
+ } & {
21
+ total_balance?: number;
22
+ };
23
+ export interface CustomerSummaryPayload extends CustomerSummaryRevenuePayload, CustomerSummaryTotalsPayload {
13
24
  customer_id: string;
14
25
  account?: {
15
26
  account_id: string;
@@ -23,6 +34,13 @@ export interface CustomerSummaryPayload extends CustomerSummaryRevenuePayload {
23
34
  currency_code?: string | null;
24
35
  currency_symbol?: string | null;
25
36
  customer_name?: string;
37
+ /** Details only: the top-level customer and every active descendant, with own and total figures. */
38
+ family_tree?: CustomerSummaryPayload[];
39
+ has_children?: boolean;
40
+ is_project?: boolean;
41
+ is_sub_customer?: boolean;
42
+ parent_customer_id?: string | null;
43
+ parent_path?: CustomerSummaryReferencePayload[];
26
44
  qbo_id?: string;
27
45
  }
28
46
  export interface CustomerSummaryListPayload {
@@ -36,3 +54,4 @@ export type CustomerSummaryListResponse = ZeniAPIResponse<CustomerSummaryListPay
36
54
  export type CustomerSummaryDetailResponse = ZeniAPIResponse<{
37
55
  customers: CustomerSummaryPayload[];
38
56
  }>;
57
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { FetchState } from '../../commonStateTypes/common';
2
2
  import { PageToken } from '../../commonStateTypes/viewAndReport/viewAndReport';
3
+ import { CustomersTabSettings } from '../../entity/tenant/tenantState';
3
4
  import { ZeniAPIStatus } from '../../responsePayload';
4
5
  import { CustomerSummaryListResponse, CustomerSummaryPayload } from './customerSummaryViewPayload';
5
6
  import { CustomerAllTransactionsTabData, CustomerDetailTabType, CustomerSummary, CustomerSummaryDetailChanges, CustomerSummarySortKey, CustomerSummaryViewState } from './customerSummaryViewState';
@@ -9,9 +10,10 @@ export declare const fetchCustomerSummaryList: import("@reduxjs/toolkit").Action
9
10
  keepExistingListItems: boolean;
10
11
  pageToken: PageToken;
11
12
  searchString: any;
12
- }, "customerSummaryView/fetchCustomerSummaryList", never, never>, updateCustomerSummaryList: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[response: CustomerSummaryListResponse, keepExistingListItems: boolean], {
13
+ }, "customerSummaryView/fetchCustomerSummaryList", never, never>, updateCustomerSummaryList: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[response: CustomerSummaryListResponse, keepExistingListItems: boolean, settings: CustomersTabSettings], {
13
14
  keepExistingListItems: boolean;
14
15
  response: CustomerSummaryListResponse;
16
+ settings: CustomersTabSettings;
15
17
  }, "customerSummaryView/updateCustomerSummaryList", never, never>, updateCustomerSummaryListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "customerSummaryView/updateCustomerSummaryListFailure">, updateCustomerSummarySortUiState: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[sortKey: CustomerSummarySortKey, sortOrder: "ascending" | "descending"], {
16
18
  sortKey: CustomerSummarySortKey;
17
19
  sortOrder: "ascending" | "descending";
@@ -1,8 +1,13 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  var _a;
3
6
  Object.defineProperty(exports, "__esModule", { value: true });
4
7
  exports.resetCustomerSummaryDetailUiState = exports.updateCustomerTrendFilter = exports.updateCustomerAllTransactionsTabData = exports.updateCustomerDetailSelectedTab = exports.updateCustomerSummarySaveState = exports.saveCustomerSummaryDetail = exports.updateCustomerSummaryDetailFailure = exports.updateCustomerSummaryDetail = exports.fetchCustomerSummaryDetail = exports.updateCustomerSummaryScrollYOffset = exports.updateCustomerSummaryRevenueSelection = exports.updateCustomerSummarySortUiState = exports.updateCustomerSummaryListFailure = exports.updateCustomerSummaryList = exports.fetchCustomerSummaryList = exports.toCustomerSummary = exports.initialState = void 0;
5
8
  const toolkit_1 = require("@reduxjs/toolkit");
9
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
10
+ const tenantReducer_1 = require("../../entity/tenant/tenantReducer");
6
11
  const rootActions_1 = require("../../rootActions");
7
12
  const customerSummaryViewState_1 = require("./customerSummaryViewState");
8
13
  exports.initialState = {
@@ -24,6 +29,9 @@ exports.initialState = {
24
29
  detailCustomerId: undefined,
25
30
  error: undefined,
26
31
  };
32
+ const toReference = (payload) => payload != null
33
+ ? { id: payload.customer_id, name: payload.customer_name ?? '' }
34
+ : undefined;
27
35
  const toCustomerSummary = (payload) => ({
28
36
  id: payload.customer_id,
29
37
  qboId: payload.qbo_id ?? undefined,
@@ -32,6 +40,22 @@ const toCustomerSummary = (payload) => ({
32
40
  currencyCode: payload.currency_code ?? undefined,
33
41
  currencySymbol: payload.currency_symbol ?? undefined,
34
42
  revenue: Object.fromEntries(customerSummaryViewState_1.CUSTOMER_REVENUE_KEYS.map((key) => [key, payload[key] ?? 0])),
43
+ hasChildren: payload.has_children === true,
44
+ isProject: payload.is_project === true,
45
+ isSubCustomer: payload.is_sub_customer === true,
46
+ parentId: payload.parent_customer_id ?? undefined,
47
+ parentPath: (payload.parent_path ?? []).flatMap((parent) => toReference(parent) ?? []),
48
+ familyTree: payload.family_tree?.map(exports.toCustomerSummary),
49
+ // Only the details response carries them
50
+ totals: payload.total_balance != null
51
+ ? {
52
+ balance: payload.total_balance,
53
+ revenue: Object.fromEntries(customerSummaryViewState_1.CUSTOMER_REVENUE_KEYS.map((key) => [
54
+ key,
55
+ payload[`total_${key}`] ?? 0,
56
+ ])),
57
+ }
58
+ : undefined,
35
59
  account: payload.account?.account_id != null
36
60
  ? {
37
61
  id: payload.account.account_id,
@@ -78,11 +102,16 @@ const customerSummaryView = (0, toolkit_1.createSlice)({
78
102
  },
79
103
  },
80
104
  updateCustomerSummaryList: {
81
- prepare(response, keepExistingListItems) {
82
- return { payload: { keepExistingListItems, response } };
105
+ prepare(response, keepExistingListItems, settings) {
106
+ return { payload: { keepExistingListItems, response, settings } };
83
107
  },
84
108
  reducer(draft, action) {
85
- const { response, keepExistingListItems } = action.payload;
109
+ const { response, keepExistingListItems, settings } = action.payload;
110
+ // A next page fetched under other settings than the listed rows: drop it, the list refetches
111
+ if (keepExistingListItems && !(0, isEqual_1.default)(draft.listSettings, settings)) {
112
+ return;
113
+ }
114
+ draft.listSettings = settings;
86
115
  const customers = (response.data?.customers ?? []).map(exports.toCustomerSummary);
87
116
  const existingIds = new Set(draft.customers.map(({ id }) => id));
88
117
  draft.customers = keepExistingListItems
@@ -131,12 +160,13 @@ const customerSummaryView = (0, toolkit_1.createSlice)({
131
160
  detail.customer = (0, exports.toCustomerSummary)(action.payload.customer);
132
161
  detail.fetchState = 'Completed';
133
162
  // Keep the list row in sync after an edit.
163
+ const { account, accountingClass } = detail.customer;
134
164
  const index = draft.customers.findIndex(({ id }) => id === action.payload.customerId);
135
165
  if (index >= 0) {
136
166
  draft.customers[index] = {
137
167
  ...draft.customers[index],
138
- account: detail.customer.account,
139
- accountingClass: detail.customer.accountingClass,
168
+ account,
169
+ accountingClass,
140
170
  };
141
171
  }
142
172
  },
@@ -193,8 +223,14 @@ const customerSummaryView = (0, toolkit_1.createSlice)({
193
223
  },
194
224
  },
195
225
  extraReducers: (builder) => {
196
- builder.addCase(rootActions_1.clearAll, (draft) => {
226
+ builder
227
+ .addCase(rootActions_1.clearAll, (draft) => {
197
228
  Object.assign(draft, exports.initialState);
229
+ })
230
+ // Totals on / off switch the detail page's All transactions tab to another entity: restart its window.
231
+ // (The list refetches through `getCustomerSummaryList`; the details carry both figures.)
232
+ .addCase(tenantReducer_1.updateTenantCustomersTabSetting, (draft) => {
233
+ draft.allTransactionsTabData = undefined;
198
234
  });
199
235
  },
200
236
  });
@@ -1,17 +1,29 @@
1
1
  import { NestedAccountHierarchyForReport } from '../../commonStateTypes/accountView/nestedAccountID';
2
2
  import { NestedClassHierarchyForReport } from '../../commonStateTypes/classesView/nestedClassID';
3
3
  import { ID } from '../../commonStateTypes/common';
4
+ import { CustomersTabSettings } from '../../entity/tenant/tenantState';
4
5
  import { RoleMap } from '../../entity/userRole/userRoleType';
5
6
  import { VendorSpendTrendFilterTabType } from '../../entity/vendorExpense/vendorSpendTrendFilterTabType';
6
7
  import { RootState } from '../../rootStateTypes';
7
- import { CustomerAllTransactionsTabData, CustomerDetailTabType, CustomerSummaryDetailState, CustomerSummaryViewState } from './customerSummaryViewState';
8
+ import { CustomerAllTransactionsTabData, CustomerDetailTabType, CustomerSummaryDetailState, CustomerSummaryFigures, CustomerSummaryViewState } from './customerSummaryViewState';
8
9
  export interface CustomerSummaryDetailView extends CustomerSummaryDetailState {
9
10
  accountsHierarchyList: NestedAccountHierarchyForReport[];
10
11
  classHierarchyList: NestedClassHierarchyForReport[];
12
+ /**
13
+ * The tenant includes sub-customers and projects in totals, and the details (once loaded) carry them: the
14
+ * figures, trend and transactions all cover them. Otherwise all of them are the customer's own.
15
+ */
16
+ includesSubCustomers: boolean;
11
17
  isAccountingClassesEnabled: boolean;
12
18
  /** Account (and, with classes on, class) list still loading: the pickers would show raw ids. */
13
19
  isReferenceDataLoading: boolean;
20
+ /** The trend / transactions entity id: the rolled-up view's id when `includesSubCustomers`. */
21
+ trendEntityId: ID;
22
+ /** The figures on show (see `includesSubCustomers`); undefined until the details load. */
23
+ figures?: CustomerSummaryFigures;
14
24
  }
25
+ export declare const getCustomersTabSettings: (state: RootState) => CustomersTabSettings;
26
+ /** Rows fetched under other Customers tab settings (however those changed) read as not fetched yet. */
15
27
  export declare const getCustomerSummaryList: (state: RootState) => CustomerSummaryViewState;
16
28
  export declare const getCustomerSummaryDetail: (state: RootState, customerId: ID) => CustomerSummaryDetailView;
17
29
  export declare const getCustomerSummarySelectedTabType: (state: RootState) => CustomerDetailTabType;
@@ -1,8 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isCustomersTabVisible = exports.getCustomerSummaryTrendFilter = exports.getCustomerSummaryAllTransactionsTabData = exports.getCustomerSummarySelectedTabType = exports.getCustomerSummaryDetail = exports.getCustomerSummaryList = void 0;
6
+ exports.isCustomersTabVisible = exports.getCustomerSummaryTrendFilter = exports.getCustomerSummaryAllTransactionsTabData = exports.getCustomerSummarySelectedTabType = exports.getCustomerSummaryDetail = exports.getCustomerSummaryList = exports.getCustomersTabSettings = void 0;
4
7
  const toolkit_1 = require("@reduxjs/toolkit");
8
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
9
+ const customerWithSubCustomersId_1 = require("../../entity/genericEntity/customerWithSubCustomersId");
5
10
  const tenantSelector_1 = require("../../entity/tenant/tenantSelector");
11
+ const tenantState_1 = require("../../entity/tenant/tenantState");
6
12
  const accountListSelector_1 = require("../accountList/accountListSelector");
7
13
  const classListSelector_1 = require("../classList/classListSelector");
8
14
  const isLoadingFetchState = (fetchState) => fetchState === 'Not-Started' || fetchState === 'In-Progress';
@@ -10,17 +16,44 @@ const NOT_STARTED_DETAIL = {
10
16
  fetchState: 'Not-Started',
11
17
  saveState: 'Not-Started',
12
18
  };
13
- const getCustomerSummaryList = (state) => state.customerSummaryViewState;
14
- exports.getCustomerSummaryList = getCustomerSummaryList;
15
- exports.getCustomerSummaryDetail = (0, toolkit_1.createSelector)((state, customerId) => state.customerSummaryViewState.detailById[customerId], (state) => state.accountListState, (state) => state.classListState, tenantSelector_1.getIsAccountingClassesEnabled, (detail, accountListState, classListState, isAccountingClassesEnabled) => ({
16
- ...(detail ?? NOT_STARTED_DETAIL),
17
- accountsHierarchyList: (0, accountListSelector_1.getNestedAccountListHierarchy)(accountListState, 'accountList'),
18
- classHierarchyList: (0, classListSelector_1.getNestedClassListHierarchy)(classListState),
19
- isAccountingClassesEnabled,
20
- isReferenceDataLoading: isLoadingFetchState(accountListState.byReportId.accountList.fetchState) ||
21
- (isAccountingClassesEnabled &&
22
- isLoadingFetchState(classListState.fetchState)),
23
- }));
19
+ const getCustomersTabSettings = (state) => {
20
+ const { currentTenantId } = state.tenantState;
21
+ return ((currentTenantId != null
22
+ ? (0, tenantSelector_1.getTenantCustomersTabSettings)(state.tenantState, currentTenantId)
23
+ : undefined) ?? tenantState_1.DEFAULT_CUSTOMERS_TAB_SETTINGS);
24
+ };
25
+ exports.getCustomersTabSettings = getCustomersTabSettings;
26
+ /** Rows fetched under other Customers tab settings (however those changed) read as not fetched yet. */
27
+ exports.getCustomerSummaryList = (0, toolkit_1.createSelector)((state) => state.customerSummaryViewState, exports.getCustomersTabSettings, (view, settings) => view.listSettings == null || (0, isEqual_1.default)(view.listSettings, settings)
28
+ ? view
29
+ : {
30
+ ...view,
31
+ customers: [],
32
+ error: undefined,
33
+ fetchState: 'Not-Started',
34
+ totalCount: 0,
35
+ uiState: { ...view.uiState, pageToken: null, scrollYOffset: 0 },
36
+ });
37
+ exports.getCustomerSummaryDetail = (0, toolkit_1.createSelector)((state, customerId) => state.customerSummaryViewState.detailById[customerId], (state) => state.accountListState, (state) => state.classListState, tenantSelector_1.getIsAccountingClassesEnabled, (state) => (0, exports.getCustomersTabSettings)(state).includeSubCustomersInTotals, (_state, customerId) => customerId, (detail, accountListState, classListState, isAccountingClassesEnabled, includeSubCustomersInTotals, customerId) => {
38
+ const customer = detail?.customer;
39
+ // Rolled up from the start (in parallel with the details); own figures if the details turn out to have no totals
40
+ const includesSubCustomers = includeSubCustomersInTotals &&
41
+ (customer == null || customer.totals != null);
42
+ return {
43
+ ...(detail ?? NOT_STARTED_DETAIL),
44
+ accountsHierarchyList: (0, accountListSelector_1.getNestedAccountListHierarchy)(accountListState, 'accountList'),
45
+ classHierarchyList: (0, classListSelector_1.getNestedClassListHierarchy)(classListState),
46
+ isAccountingClassesEnabled,
47
+ isReferenceDataLoading: isLoadingFetchState(accountListState.byReportId.accountList.fetchState) ||
48
+ (isAccountingClassesEnabled &&
49
+ isLoadingFetchState(classListState.fetchState)),
50
+ includesSubCustomers,
51
+ figures: includesSubCustomers ? customer?.totals : customer,
52
+ trendEntityId: includesSubCustomers
53
+ ? (0, customerWithSubCustomersId_1.toCustomerWithSubCustomersId)(customerId)
54
+ : customerId,
55
+ };
56
+ });
24
57
  const getCustomerSummarySelectedTabType = (state) => state.customerSummaryViewState.selectedTabType;
25
58
  exports.getCustomerSummarySelectedTabType = getCustomerSummarySelectedTabType;
26
59
  const getCustomerSummaryAllTransactionsTabData = (state) => state.customerSummaryViewState.allTransactionsTabData;
@@ -2,27 +2,38 @@ import { FetchState, ID } from '../../commonStateTypes/common';
2
2
  import { SortOrder } from '../../commonStateTypes/selectorTypes/sortOrderTypes';
3
3
  import { TimePeriod } from '../../commonStateTypes/timePeriod';
4
4
  import { PageToken } from '../../commonStateTypes/viewAndReport/viewAndReport';
5
+ import { CustomersTabSettings } from '../../entity/tenant/tenantState';
5
6
  import { VendorSpendTrendFilterTabType } from '../../entity/vendorExpense/vendorSpendTrendFilterTabType';
6
7
  import { ZeniAPIStatus } from '../../responsePayload';
7
8
  export declare const CUSTOMER_REVENUE_KEYS: readonly ["last_90_days_revenue", "last_30_days_revenue", "year_to_date_revenue", "last_month_revenue", "last_3_months_revenue", "last_6_months_revenue", "last_12_months_revenue", "previous_year_revenue"];
8
9
  export type CustomerRevenueKey = (typeof CUSTOMER_REVENUE_KEYS)[number];
9
10
  export type CustomerSummarySortKey = 'customer_name' | 'account' | 'accounting_class' | 'balance' | CustomerRevenueKey;
10
- export interface CustomerSummary {
11
- balance: number;
11
+ export interface CustomerSummaryReference {
12
12
  id: ID;
13
13
  name: string;
14
+ }
15
+ export interface CustomerSummaryFigures {
16
+ balance: number;
14
17
  revenue: Record<CustomerRevenueKey, number>;
15
- account?: {
16
- id: ID;
17
- name: string;
18
- };
19
- accountingClass?: {
20
- id: ID;
21
- name: string;
22
- };
18
+ }
19
+ export interface CustomerSummary extends CustomerSummaryFigures {
20
+ hasChildren: boolean;
21
+ id: ID;
22
+ isProject: boolean;
23
+ isSubCustomer: boolean;
24
+ name: string;
25
+ /** Root-first ancestors, for the "Parent › Child" label; empty for a top-level customer. */
26
+ parentPath: CustomerSummaryReference[];
27
+ account?: CustomerSummaryReference;
28
+ accountingClass?: CustomerSummaryReference;
23
29
  currencyCode?: string;
24
30
  currencySymbol?: string;
31
+ /** Details only: the whole family it belongs to (its top-level customer and every active descendant), flat. */
32
+ familyTree?: CustomerSummary[];
33
+ parentId?: ID;
25
34
  qboId?: ID;
35
+ /** Details only: the figures over the customer and all its active sub-customers and projects. */
36
+ totals?: CustomerSummaryFigures;
26
37
  }
27
38
  export interface CustomerSummaryListUIState {
28
39
  pageToken: PageToken;
@@ -48,6 +59,7 @@ export interface CustomerSummaryDetailState {
48
59
  error?: ZeniAPIStatus;
49
60
  }
50
61
  export interface CustomerSummaryViewState {
62
+ /** Every level, or only top-level customers (the tenant's Customers tab settings). */
51
63
  customers: CustomerSummary[];
52
64
  detailById: Record<ID, CustomerSummaryDetailState>;
53
65
  fetchState: FetchState;
@@ -60,4 +72,6 @@ export interface CustomerSummaryViewState {
60
72
  /** Customer the detail page UI state (filter, tab, transactions window) belongs to. */
61
73
  detailCustomerId?: ID;
62
74
  error?: ZeniAPIStatus;
75
+ /** The Customers tab settings the listed rows were fetched with. */
76
+ listSettings?: CustomersTabSettings;
63
77
  }