@zeniai/client-epic-state 5.0.52 → 5.0.53-betaML3

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 (124) hide show
  1. package/lib/commonStateTypes/recommendationBase.d.ts +2 -1
  2. package/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
  3. package/lib/commonStateTypes/viewAndReport/viewAndReport.js +1 -0
  4. package/lib/entity/account/accountState.d.ts +1 -1
  5. package/lib/entity/accountGroup/accountGroupState.d.ts +1 -1
  6. package/lib/entity/class/classReducer.d.ts +4 -4
  7. package/lib/entity/class/classState.d.ts +1 -1
  8. package/lib/entity/forecast/forecastState.d.ts +1 -1
  9. package/lib/entity/project/projectPayload.d.ts +8 -1
  10. package/lib/entity/project/projectPayload.js +15 -1
  11. package/lib/entity/project/projectState.d.ts +4 -2
  12. package/lib/entity/sectionAccountsView/sectionAccountsView.d.ts +1 -1
  13. package/lib/entity/sectionClassesViewV2/sectionClassesView.d.ts +1 -1
  14. package/lib/entity/sectionClassesViewV2/sectionClassesViewReducer.d.ts +2 -2
  15. package/lib/entity/sectionProjectView/sectionProjectView.d.ts +1 -1
  16. package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +2 -2
  17. package/lib/entity/tenant/clearAllEpic.d.ts +2 -1
  18. package/lib/entity/tenant/clearAllEpic.js +2 -0
  19. package/lib/entity/transaction/payloadTypes/transactionLinePayload.d.ts +2 -0
  20. package/lib/entity/transaction/payloadTypes/transactionLinePayload.js +9 -0
  21. package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +2 -0
  22. package/lib/entity/transaction/payloadTypes/transactionPayload.js +6 -0
  23. package/lib/entity/transaction/stateTypes/transaction.d.ts +2 -0
  24. package/lib/entity/transaction/stateTypes/transactionLine.d.ts +2 -0
  25. package/lib/epic.d.ts +4 -1
  26. package/lib/epic.js +5 -1
  27. package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +1 -0
  28. package/lib/esm/entity/project/projectPayload.js +12 -0
  29. package/lib/esm/entity/tenant/clearAllEpic.js +2 -0
  30. package/lib/esm/entity/transaction/payloadTypes/transactionLinePayload.js +9 -0
  31. package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +6 -0
  32. package/lib/esm/epic.js +5 -1
  33. package/lib/esm/index.js +11 -7
  34. package/lib/esm/reducer.js +3 -0
  35. package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +8 -0
  36. package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic.js +3 -0
  37. package/lib/esm/view/expenseAutomationView/helpers/saveTransactionHelper.js +1 -0
  38. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +11 -2
  39. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +100 -31
  40. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +13 -2
  41. package/lib/esm/view/expenseAutomationView/types/transactionsViewState.js +1 -0
  42. package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +44 -0
  43. package/lib/esm/view/projectList/fetchProjectListEpic.js +38 -0
  44. package/lib/esm/view/projectList/projectListPayload.js +1 -0
  45. package/lib/esm/view/projectList/projectListReducer.js +39 -0
  46. package/lib/esm/view/projectList/projectListSelector.js +9 -0
  47. package/lib/esm/view/projectList/projectListState.js +1 -0
  48. package/lib/esm/view/recommendation/fetchEntityRecommendationsForCategorizationEpic.js +83 -0
  49. package/lib/esm/view/recommendation/recommendationReducer.js +52 -1
  50. package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +1 -0
  51. package/lib/esm/view/transactionDetail/epics/transactionDetailEpic.js +6 -0
  52. package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +3 -0
  53. package/lib/esm/view/transactionDetail/transactionDetailSelector.js +14 -2
  54. package/lib/esm/view/transactionList/fetchTransactionListByProjectEpic.js +45 -0
  55. package/lib/esm/view/transactionList/parallelFetchProjectTransactionListEpic.js +32 -0
  56. package/lib/esm/view/transactionList/transactionListByProjectSelector.js +58 -0
  57. package/lib/esm/view/transactionList/transactionListReducer.js +83 -2
  58. package/lib/esm/view/transactionList/transactionListState.js +10 -0
  59. package/lib/index.d.ts +13 -9
  60. package/lib/index.js +42 -27
  61. package/lib/reducer.d.ts +3 -0
  62. package/lib/reducer.js +3 -0
  63. package/lib/tsconfig.typecheck.tsbuildinfo +1 -0
  64. package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
  65. package/lib/view/billPayCard/billPayCardSelector.d.ts +1 -1
  66. package/lib/view/cardBalance/cardBalanceSelector.d.ts +1 -1
  67. package/lib/view/cashBalance/cashBalanceSelector.d.ts +1 -1
  68. package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +1 -1
  69. package/lib/view/cashPosition/cashPositionSelector.d.ts +1 -1
  70. package/lib/view/dashboard/dashboardReducer.d.ts +2 -2
  71. package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.d.ts +2 -1
  72. package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +8 -0
  73. package/lib/view/expenseAutomationView/epics/transactionCategorization/updateTransactionCategorizationEpic.js +3 -0
  74. package/lib/view/expenseAutomationView/helpers/saveTransactionHelper.js +1 -0
  75. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +2 -1
  76. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +11 -2
  77. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +3 -1
  78. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +100 -31
  79. package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +4 -0
  80. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -1
  81. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +5 -1
  82. package/lib/view/expenseAutomationView/types/transactionsViewState.js +1 -0
  83. package/lib/view/financeStatement/financeStatementReducer.d.ts +1 -1
  84. package/lib/view/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
  85. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.d.ts +15 -1
  86. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +45 -0
  87. package/lib/view/projectList/fetchProjectListEpic.d.ts +8 -0
  88. package/lib/view/projectList/fetchProjectListEpic.js +42 -0
  89. package/lib/view/projectList/projectListPayload.d.ts +7 -0
  90. package/lib/view/projectList/projectListPayload.js +2 -0
  91. package/lib/view/projectList/projectListReducer.d.ts +9 -0
  92. package/lib/view/projectList/projectListReducer.js +43 -0
  93. package/lib/view/projectList/projectListSelector.d.ts +8 -0
  94. package/lib/view/projectList/projectListSelector.js +13 -0
  95. package/lib/view/projectList/projectListState.d.ts +4 -0
  96. package/lib/view/projectList/projectListState.js +2 -0
  97. package/lib/view/recommendation/fetchEntityRecommendationsForCategorizationEpic.d.ts +8 -0
  98. package/lib/view/recommendation/fetchEntityRecommendationsForCategorizationEpic.js +87 -0
  99. package/lib/view/recommendation/recommendationReducer.d.ts +21 -1
  100. package/lib/view/recommendation/recommendationReducer.js +53 -2
  101. package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
  102. package/lib/view/reportsResync/reportsResyncReducer.d.ts +2 -2
  103. package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
  104. package/lib/view/topEx/topExSelector.d.ts +1 -1
  105. package/lib/view/transactionDetail/epics/saveTransactionHelper.js +1 -0
  106. package/lib/view/transactionDetail/epics/transactionDetailEpic.d.ts +2 -1
  107. package/lib/view/transactionDetail/epics/transactionDetailEpic.js +6 -0
  108. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +3 -0
  109. package/lib/view/transactionDetail/transactionDetailSelector.d.ts +3 -0
  110. package/lib/view/transactionDetail/transactionDetailSelector.js +13 -1
  111. package/lib/view/transactionDetail/transactionDetailState.d.ts +2 -0
  112. package/lib/view/transactionDetail/transactionDetailTypes.d.ts +2 -0
  113. package/lib/view/transactionList/fetchTransactionListByProjectEpic.d.ts +8 -0
  114. package/lib/view/transactionList/fetchTransactionListByProjectEpic.js +52 -0
  115. package/lib/view/transactionList/parallelFetchProjectTransactionListEpic.d.ts +6 -0
  116. package/lib/view/transactionList/parallelFetchProjectTransactionListEpic.js +36 -0
  117. package/lib/view/transactionList/transactionListByProjectSelector.d.ts +22 -0
  118. package/lib/view/transactionList/transactionListByProjectSelector.js +66 -0
  119. package/lib/view/transactionList/transactionListPayload.d.ts +15 -0
  120. package/lib/view/transactionList/transactionListReducer.d.ts +25 -2
  121. package/lib/view/transactionList/transactionListReducer.js +83 -2
  122. package/lib/view/transactionList/transactionListState.d.ts +15 -0
  123. package/lib/view/transactionList/transactionListState.js +13 -1
  124. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { ZeniDate } from '../../zeniDayJS';
5
5
  import { AuditSummary } from '../reviewCompanyView/reviewCompanyViewState';
6
6
  export declare const toAuditRuleEntityType: (v: string) => "dashboard" | "transactions" | "reports";
7
7
  export type AuditRuleEntityType = ReturnType<typeof toAuditRuleEntityType>;
8
- declare const toAuditRuleEntityIdType: (v: string) => "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation" | "uncategorized-expense" | "uncategorized-income";
8
+ declare const toAuditRuleEntityIdType: (v: string) => "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation" | "uncategorized-expense" | "uncategorized-income";
9
9
  export type AuditRuleEntityIdType = ReturnType<typeof toAuditRuleEntityIdType>;
10
10
  export declare const toAuditRuleTypeIdType: (v: string) => "accounting" | "business";
11
11
  type AuditRuleTypeIdType = ReturnType<typeof toAuditRuleTypeIdType>;
@@ -1,6 +1,6 @@
1
1
  import { RootState } from '../../reducer';
2
2
  export declare const getBillPayCardReport: (state: RootState) => {
3
- reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
3
+ reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
4
4
  reportTitle: string;
5
5
  version: string | number | undefined;
6
6
  fetchState: import("../..").FetchState;
@@ -1,6 +1,6 @@
1
1
  import { RootState } from '../../reducer';
2
2
  export declare const getCardBalance: (state: RootState) => {
3
- reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
3
+ reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
4
4
  reportTitle: string;
5
5
  version: string | number | undefined;
6
6
  status: import("../..").Status | undefined;
@@ -1,6 +1,6 @@
1
1
  import { RootState } from '../../reducer';
2
2
  export declare const getCashBalance: (state: RootState) => {
3
- reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
3
+ reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
4
4
  reportTitle: string;
5
5
  version: string | number | undefined;
6
6
  status: import("../..").Status | undefined;
@@ -15,7 +15,7 @@ export declare const getCashInCashOut: (accountState: AccountState, accountGroup
15
15
  firstMonthOfFY: 1 | 3 | 12 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
16
16
  dataAvailable: import("../../commonStateTypes/timeframeTick").TimeframeTick | undefined;
17
17
  availableNumberOfPeriods: number | undefined;
18
- reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
18
+ reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
19
19
  reportTitle: string;
20
20
  version: string | number | undefined;
21
21
  status: import("../..").Status | undefined;
@@ -12,7 +12,7 @@ export declare const getCashPosition: (accountState: AccountState, cashPositionS
12
12
  firstMonthOfFY: 1 | 3 | 12 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
13
13
  dataAvailable: import("../../commonStateTypes/timeframeTick").TimeframeTick | undefined;
14
14
  availableNumberOfPeriods: number | undefined;
15
- reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
15
+ reportId: "cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation";
16
16
  reportTitle: string;
17
17
  version: string | number | undefined;
18
18
  status: import("../..").Status | undefined;
@@ -1,12 +1,12 @@
1
1
  import { DashboardState } from './dashboardState';
2
2
  export declare const initialState: DashboardState;
3
- export declare const fetchDashboard: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, companyId: string, tenantId: string, fetchFullReport?: any, cacheOverride?: any, excludeResources?: ("cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation")[] | undefined], {
3
+ export declare const fetchDashboard: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, companyId: string, tenantId: string, fetchFullReport?: any, cacheOverride?: any, excludeResources?: ("cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation")[] | undefined], {
4
4
  userId: string;
5
5
  companyId: string;
6
6
  tenantId: string;
7
7
  fetchFullReport: any;
8
8
  cacheOverride: any;
9
- excludeResources: ("cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation")[];
9
+ excludeResources: ("cash_balance" | "card_balance" | "expense_automation_card" | "operating_expenses" | "operating_expenses_by_classes" | "revenue" | "revenue_by_classes" | "net_burn_or_income" | "net_burn_or_income_story_card" | "net_burn_or_income_by_classes" | "cash_position" | "top_expenses" | "profit_and_loss" | "profit_and_loss_by_classes" | "profit_and_loss_by_projects" | "balance_sheet" | "cash_flow" | "dashboard" | "finance_statement" | "transaction_list_of_account" | "transaction_list_missing_receipt" | "transaction_list_of_account_by_class" | "transaction_list_of_account_by_project" | "transaction_detail" | "cash_in_cash_out" | "insights_dashboard" | "company_details" | "class_list" | "account_list" | "account_list_by_type" | "vendor" | "task_card" | "bill_pay" | "reimbursement" | "bill_pay_card" | "reimbursement_card" | "bill_pay_promo_card" | "zeni_accounts" | "zeni_accounts_promo_card" | "zeni_treasury" | "charge_cards" | "other_connection" | "reimbursement_promo_card" | "onboarding" | "operating_expenses_by_vendor" | "operating_expenses_by_vendor_summary" | "vendors_tab" | "accounts_payable_aging" | "accounts_receivable_aging" | "vendor_global_review" | "prepaid_expenses" | "fixed_assets" | "notification" | "rewards_card" | "billing" | "flux_analysis_operating_expense" | "account_reconciliation" | "zeni_credit_promo_card" | "treasury_promo_card" | "excluded_account_reconciliation")[];
10
10
  }, "dashboard/fetchDashboard", never, never>, updateTreasuryVideoClosed: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"dashboard/updateTreasuryVideoClosed">, clearDashboard: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"dashboard/clearDashboard">;
11
11
  declare const _default: import("redux").Reducer<DashboardState>;
12
12
  export default _default;
@@ -4,6 +4,7 @@ import { RootState } from '../../../../reducer';
4
4
  import { fetchAccountList } from '../../../accountList/accountListReducer';
5
5
  import { fetchClassList } from '../../../classList/classListReducer';
6
6
  import { fetchOwnerList } from '../../../ownerList/ownerListReducer';
7
+ import { fetchProjectList } from '../../../projectList/projectListReducer';
7
8
  import { fetchTransactionCategorization, fetchTransactionCategorizationView } from '../../reducers/transactionsViewReducer';
8
- export type ActionType = ReturnType<typeof fetchTransactionCategorizationView> | ReturnType<typeof fetchTransactionCategorization> | ReturnType<typeof fetchAccountList> | ReturnType<typeof fetchClassList> | ReturnType<typeof fetchOwnerList>;
9
+ export type ActionType = ReturnType<typeof fetchTransactionCategorizationView> | ReturnType<typeof fetchTransactionCategorization> | ReturnType<typeof fetchAccountList> | ReturnType<typeof fetchClassList> | ReturnType<typeof fetchOwnerList> | ReturnType<typeof fetchProjectList>;
9
10
  export declare const fetchTransactionCategorizationViewEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
@@ -4,9 +4,11 @@ exports.fetchTransactionCategorizationViewEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const timePeriod_1 = require("../../../../commonStateTypes/timePeriod");
7
+ const tenantSelector_1 = require("../../../../entity/tenant/tenantSelector");
7
8
  const accountListReducer_1 = require("../../../accountList/accountListReducer");
8
9
  const classListReducer_1 = require("../../../classList/classListReducer");
9
10
  const ownerListReducer_1 = require("../../../ownerList/ownerListReducer");
11
+ const projectListReducer_1 = require("../../../projectList/projectListReducer");
10
12
  const transactionsViewReducer_1 = require("../../reducers/transactionsViewReducer");
11
13
  const fetchTransactionCategorizationViewEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(transactionsViewReducer_1.fetchTransactionCategorizationView.match), (0, operators_1.mergeMap)((action) => {
12
14
  const { selectedTab, cacheOverride, keepExistingListItems, pageToken, period, refreshViewInBackground, searchString, resetListItems, isUncategorizedExpenseCategoryEnabled, } = action.payload;
@@ -29,6 +31,12 @@ const fetchTransactionCategorizationViewEpic = (actions$, state$) => actions$.pi
29
31
  classList.fetchState === 'Not-Started') {
30
32
  updateActions.push((0, classListReducer_1.fetchClassList)());
31
33
  }
34
+ const projectList = state$.value.projectListState;
35
+ if ((0, tenantSelector_1.getIsAccountingProjectsEnabled)(state$.value) &&
36
+ projectList.hasValidState() === false &&
37
+ projectList.fetchState === 'Not-Started') {
38
+ updateActions.push((0, projectListReducer_1.fetchProjectList)());
39
+ }
32
40
  const vendorOwnerList = state$.value.ownerListState;
33
41
  if (vendorOwnerList.hasValidState() === false &&
34
42
  vendorOwnerList.fetchState === 'Not-Started') {
@@ -117,6 +117,9 @@ const toTransactionUpdatePayload = (updates, detail, transactionId, cotTrackingB
117
117
  if (lineUpdates.class != null) {
118
118
  lineToBeUpdated.class = lineUpdates.class;
119
119
  }
120
+ if (lineUpdates.project != null) {
121
+ lineToBeUpdated.project = lineUpdates.project;
122
+ }
120
123
  if (lineUpdates.account != null) {
121
124
  lineToBeUpdated.account = lineUpdates.account;
122
125
  }
@@ -44,6 +44,7 @@ const toTransactionUpdatesFromTransactionCategorizationLocalData = (transactionC
44
44
  lineDescription: lineItem.lineDescription,
45
45
  class: lineItem.class,
46
46
  account: lineItem.account,
47
+ project: lineItem.project,
47
48
  recommendation: (0, transactionHelper_1.convertCOTRecommendationsToRegular)(lineItem.recommendationsWithCOT),
48
49
  };
49
50
  if (line.type === 'journal_entry_transaction_line' ||
@@ -2,6 +2,7 @@ import { ID } from '../../../commonStateTypes/common';
2
2
  import { AccountBase } from '../../../entity/account/accountState';
3
3
  import { UncategorizedAccountTypes } from '../../../entity/account/accountState';
4
4
  import { ClassBase } from '../../../entity/class/classState';
5
+ import { ProjectBase } from '../../../entity/project/projectState';
5
6
  import { Entity } from '../../../entity/genericEntity/entity';
6
7
  import { RecommendationWithCOTByLineId } from '../../../entity/transaction/stateTypes/transaction';
7
8
  import { SupportedTransactionPayload, SupportedTransactionWithCOT } from '../../../entity/transaction/transactionState';
@@ -27,7 +28,7 @@ export declare const removeTransactionFromTabView: (tabView: TransactionsTabView
27
28
  export declare const filterAutoTabLineItems: (tabView: TransactionsTabViewState, transactionId: ID, updatedTransaction: SupportedTransactionWithCOT) => void;
28
29
  export declare const MAX_SELECTION_LIMIT = 5;
29
30
  export declare const toTransactionDetailLocalData: (transaction: SupportedTransactionWithCOT, selectedTab: TransactionsTab, lineItemsByTransactionIds: string[], uncategorizedIncomeExpense: UncategorizedAccounts, isUncategorizedExpenseCategoryEnabled?: boolean) => TransactionReviewLocalData;
30
- export declare const toSetAllLineItemsToCategoryClass: (draft: TransactionsTabViewState, transaction: SupportedTransactionWithCOT, transactionId: ID, transactionLineId: ID, transactionDetailLocalData: TransactionReviewLocalData, updatedItem: "category" | "class", uncategorizedAccounts: UncategorizedAccounts, selectedTab: TransactionsTab, vendorId?: ID, customerId?: ID, selectedAccount?: AccountBase, selectedClassBase?: ClassBase, isUncategorizedExpenseCategoryEnabled?: boolean, isAccountingClassesEnabled?: boolean) => {
31
+ export declare const toSetAllLineItemsToCategoryClass: (draft: TransactionsTabViewState, transaction: SupportedTransactionWithCOT, transactionId: ID, transactionLineId: ID, transactionDetailLocalData: TransactionReviewLocalData, updatedItem: "category" | "class" | "project", uncategorizedAccounts: UncategorizedAccounts, selectedTab: TransactionsTab, vendorId?: ID, customerId?: ID, selectedAccount?: AccountBase, selectedClassBase?: ClassBase, selectedProjectBase?: ProjectBase, isUncategorizedExpenseCategoryEnabled?: boolean, isAccountingClassesEnabled?: boolean) => {
31
32
  localData: TransactionReviewLocalData;
32
33
  similarTransactionUpdated: boolean;
33
34
  };
@@ -190,6 +190,7 @@ const buildLineItemById = (transaction, uncategorizedIncomeExpense, recommendati
190
190
  const lineId = line.id;
191
191
  record.account = accountLine.account;
192
192
  record.class = accountLine.class;
193
+ record.project = accountLine.project;
193
194
  record.vendor =
194
195
  accountLine.vendor != null
195
196
  ? {
@@ -312,7 +313,7 @@ const buildLineItemById = (transaction, uncategorizedIncomeExpense, recommendati
312
313
  });
313
314
  return lineItemData;
314
315
  };
315
- const toSetAllLineItemsToCategoryClass = (draft, transaction, transactionId, transactionLineId, transactionDetailLocalData, updatedItem, uncategorizedAccounts, selectedTab, vendorId, customerId, selectedAccount, selectedClassBase, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) => {
316
+ const toSetAllLineItemsToCategoryClass = (draft, transaction, transactionId, transactionLineId, transactionDetailLocalData, updatedItem, uncategorizedAccounts, selectedTab, vendorId, customerId, selectedAccount, selectedClassBase, selectedProjectBase, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) => {
316
317
  let newLineItems = {};
317
318
  let selectedCheckBoxTransactionIds = draft.selectedCheckBoxTransactionIds;
318
319
  let similarTransactionUpdated = false;
@@ -332,7 +333,7 @@ const toSetAllLineItemsToCategoryClass = (draft, transaction, transactionId, tra
332
333
  const record = {
333
334
  ...transactionDetailLocalData.lineItemById[lineId],
334
335
  };
335
- // if the line is the one that is being updated, then set the account and class
336
+ // if the line is the one that is being updated, then set the account, class, and project
336
337
  if (transactionId === record.transactionId &&
337
338
  transactionLineId === lineId) {
338
339
  if (selectedAccount != null) {
@@ -341,6 +342,9 @@ const toSetAllLineItemsToCategoryClass = (draft, transaction, transactionId, tra
341
342
  if (selectedClassBase != null) {
342
343
  record.class = selectedClassBase;
343
344
  }
345
+ if (selectedProjectBase != null) {
346
+ record.project = selectedProjectBase;
347
+ }
344
348
  const isClassSatisfied = isAccountingClassesEnabled === false || record.class != null;
345
349
  if (isClassSatisfied && record.account != null) {
346
350
  if (selectedCheckBoxTransactionIds.length < exports.MAX_SELECTION_LIMIT &&
@@ -392,6 +396,10 @@ const toSetAllLineItemsToCategoryClass = (draft, transaction, transactionId, tra
392
396
  selectedCheckBoxTransactionIds.push(transaction.id);
393
397
  }
394
398
  }
399
+ // Project intentionally does NOT propagate to other rows of
400
+ // the same vendor: each line can carry a different project,
401
+ // and auto-filling siblings (the way class does) leads to
402
+ // unexpected bulk selection.
395
403
  }
396
404
  }
397
405
  if (line.type === 'transaction_with_product_or_service_line') {
@@ -522,6 +530,7 @@ const setEntityRecommendationForLineIdInLocalData = (draft, transaction, transac
522
530
  ...newLineItem,
523
531
  class: matchingRecord.class,
524
532
  account: matchingRecord.account,
533
+ project: matchingRecord.project,
525
534
  lineEntity: matchingRecord.lineEntity,
526
535
  };
527
536
  }
@@ -4,6 +4,7 @@ import { MonthYearPeriod, TimePeriod } from '../../../commonStateTypes/timePerio
4
4
  import { PageToken } from '../../../commonStateTypes/viewAndReport/viewAndReport';
5
5
  import { AccountBase } from '../../../entity/account/accountState';
6
6
  import { ClassBase } from '../../../entity/class/classState';
7
+ import { ProjectBase } from '../../../entity/project/projectState';
7
8
  import { CustomerBase } from '../../../entity/customer/customerState';
8
9
  import { Entity } from '../../../entity/genericEntity/entity';
9
10
  import { RecommendationWithCOTByLineId, TransactionID } from '../../../entity/transaction/stateTypes/transaction';
@@ -100,7 +101,7 @@ export declare const fetchTransactionCategorization: import("@reduxjs/toolkit").
100
101
  isUncategorizedExpenseCategoryEnabled?: boolean;
101
102
  selectedEntity?: Entity;
102
103
  updatedCustomer?: CustomerBase;
103
- }, "expenseAutomationTransactionsView/updateSelectedCustomerForTransaction">, setAllItemsToCategoryClassInLocalDataForCategorization: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionId: string, lineId: string, transactions: SupportedTransactionWithCOT[], uncategorizedAccounts: UncategorizedAccounts, vendorId?: string | undefined, customerId?: string | undefined, selectedAccount?: AccountBase | undefined, selectedClassBase?: ClassBase | undefined, lineEntity?: Entity | undefined, recommendations?: RecommendationWithCOT[] | undefined, isUncategorizedExpenseCategoryEnabled?: boolean | undefined, isAccountingClassesEnabled?: boolean | undefined], {
104
+ }, "expenseAutomationTransactionsView/updateSelectedCustomerForTransaction">, setAllItemsToCategoryClassInLocalDataForCategorization: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionId: string, lineId: string, transactions: SupportedTransactionWithCOT[], uncategorizedAccounts: UncategorizedAccounts, vendorId?: string | undefined, customerId?: string | undefined, selectedAccount?: AccountBase | undefined, selectedClassBase?: ClassBase | undefined, lineEntity?: Entity | undefined, recommendations?: RecommendationWithCOT[] | undefined, isUncategorizedExpenseCategoryEnabled?: boolean | undefined, isAccountingClassesEnabled?: boolean | undefined, selectedProjectBase?: ProjectBase | undefined], {
104
105
  selectedTab: "review" | "autoCategorized";
105
106
  transactionId: string;
106
107
  lineId: string;
@@ -110,6 +111,7 @@ export declare const fetchTransactionCategorization: import("@reduxjs/toolkit").
110
111
  lineEntity: Entity | undefined;
111
112
  selectedAccount: AccountBase | undefined;
112
113
  selectedClassBase: ClassBase | undefined;
114
+ selectedProjectBase: ProjectBase | undefined;
113
115
  recommendations: RecommendationWithCOT[] | undefined;
114
116
  uncategorizedAccounts: UncategorizedAccounts;
115
117
  isAccountingClassesEnabled: boolean | undefined;
@@ -8,6 +8,7 @@ exports.uploadTransactionCategorizationReceiptSuccess = exports.updateTransactio
8
8
  const toolkit_1 = require("@reduxjs/toolkit");
9
9
  const get_1 = __importDefault(require("lodash/get"));
10
10
  const uniq_1 = __importDefault(require("lodash/uniq"));
11
+ const recommendationReducer_1 = require("../../recommendation/recommendationReducer");
11
12
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
12
13
  const vendorTransaction_1 = require("../../../entity/transaction/stateTypes/vendorTransaction");
13
14
  const transactionCategorizationLocalDataHelper_1 = require("../helpers/transactionCategorizationLocalDataHelper");
@@ -289,7 +290,7 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
289
290
  },
290
291
  setAllItemsToCategoryClassInLocalDataForCategorization: {
291
292
  reducer(draft, action) {
292
- const { vendorId, customerId, selectedAccount, selectedClassBase, transactions, transactionId, lineId, selectedTab, uncategorizedAccounts, isAccountingClassesEnabled, isUncategorizedExpenseCategoryEnabled, } = action.payload;
293
+ const { vendorId, customerId, selectedAccount, selectedClassBase, selectedProjectBase, transactions, transactionId, lineId, selectedTab, uncategorizedAccounts, isAccountingClassesEnabled, isUncategorizedExpenseCategoryEnabled, } = action.payload;
293
294
  const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
294
295
  .transactionReviewLocalDataById, transactionId, undefined);
295
296
  const existingAccount = transactionLocalData?.transactionReviewLocalData.lineItemById[lineId]
@@ -303,6 +304,7 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
303
304
  ...transactionLocalData.transactionReviewLocalData.lineItemById[lineId],
304
305
  account: selectedAccount,
305
306
  class: selectedClassBase,
307
+ project: selectedProjectBase,
306
308
  },
307
309
  },
308
310
  };
@@ -331,9 +333,16 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
331
333
  const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
332
334
  .transactionReviewLocalDataById, transaction.id, undefined);
333
335
  if (transactionLocalData != null) {
334
- const { localData, similarTransactionUpdated } = (0, transactionCategorizationLocalDataHelper_1.toSetAllLineItemsToCategoryClass)(draft.transactionCategorizationView[selectedTab], transaction, transactionId, lineId, transactionLocalData.transactionReviewLocalData, existingAccount?.accountId !== selectedAccount?.accountId
336
+ const existingClassId = transactionLocalData.transactionReviewLocalData.lineItemById[lineId]?.class?.classId;
337
+ const existingProjectId = transactionLocalData.transactionReviewLocalData.lineItemById[lineId]?.project?.projectId;
338
+ const updatedItem = existingAccount?.accountId !== selectedAccount?.accountId
335
339
  ? 'category'
336
- : 'class', uncategorizedAccounts, selectedTab, vendorId, customerId, selectedAccount, selectedClassBase, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled);
340
+ : existingClassId !== selectedClassBase?.classId
341
+ ? 'class'
342
+ : existingProjectId !== selectedProjectBase?.projectId
343
+ ? 'project'
344
+ : 'class';
345
+ const { localData, similarTransactionUpdated } = (0, transactionCategorizationLocalDataHelper_1.toSetAllLineItemsToCategoryClass)(draft.transactionCategorizationView[selectedTab], transaction, transactionId, lineId, transactionLocalData.transactionReviewLocalData, updatedItem, uncategorizedAccounts, selectedTab, vendorId, customerId, selectedAccount, selectedClassBase, selectedProjectBase, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled);
337
346
  draft.transactionCategorizationView[selectedTab].transactionReviewLocalDataById[transaction.id] = {
338
347
  transactionId: transaction.id,
339
348
  transactionReviewLocalData: localData,
@@ -352,7 +361,7 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
352
361
  ...dirtyIds,
353
362
  ]);
354
363
  },
355
- prepare(selectedTab, transactionId, lineId, transactions, uncategorizedAccounts, vendorId, customerId, selectedAccount, selectedClassBase, lineEntity, recommendations, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) {
364
+ prepare(selectedTab, transactionId, lineId, transactions, uncategorizedAccounts, vendorId, customerId, selectedAccount, selectedClassBase, lineEntity, recommendations, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled, selectedProjectBase) {
356
365
  return {
357
366
  payload: {
358
367
  selectedTab,
@@ -364,6 +373,7 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
364
373
  lineEntity,
365
374
  selectedAccount,
366
375
  selectedClassBase,
376
+ selectedProjectBase,
367
377
  recommendations,
368
378
  uncategorizedAccounts,
369
379
  isAccountingClassesEnabled,
@@ -394,9 +404,25 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
394
404
  const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
395
405
  .transactionReviewLocalDataById, transactionId.id, undefined);
396
406
  if (transactionLocalData != null) {
407
+ const newLocalData = (0, transactionCategorizationLocalDataHelper_1.setEntityRecommendationForLineIdInLocalData)(draft.transactionCategorizationView[selectedTab], transaction, transactionLocalData.transactionReviewLocalData, entity, lineIds, uncategorizedAccounts, action.payload.recommendationWithCOTByLineId, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled);
408
+ // Flip the per-line "fetching" flag to Completed for the lines this
409
+ // fetch covered. Reads as the success arm of the
410
+ // fetchEntityRecommendationsForCategorization → epic → reducer cycle.
411
+ lineIds.forEach((lineId) => {
412
+ const lineItem = newLocalData.lineItemById[lineId];
413
+ if (lineItem != null) {
414
+ newLocalData.lineItemById[lineId] = {
415
+ ...lineItem,
416
+ categoryClassRecommendationsFetchState: {
417
+ fetchState: 'Completed',
418
+ error: undefined,
419
+ },
420
+ };
421
+ }
422
+ });
397
423
  draft.transactionCategorizationView[selectedTab].transactionReviewLocalDataById[transaction.id] = {
398
424
  transactionId: transaction.id,
399
- transactionReviewLocalData: (0, transactionCategorizationLocalDataHelper_1.setEntityRecommendationForLineIdInLocalData)(draft.transactionCategorizationView[selectedTab], transaction, transactionLocalData.transactionReviewLocalData, entity, lineIds, uncategorizedAccounts, action.payload.recommendationWithCOTByLineId, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled),
425
+ transactionReviewLocalData: newLocalData,
400
426
  };
401
427
  // Mark transaction as dirty (autofill happened)
402
428
  if (!draft.transactionCategorizationView[selectedTab].transactionIdsWithUnsavedData.includes(transaction.id)) {
@@ -451,7 +477,13 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
451
477
  action.payload.status;
452
478
  },
453
479
  updateSelectedCustomerForTransaction(draft, action) {
454
- const { transactionId, lineId, updatedCustomer, selectedTransaction, selectedTab, uncategorizedAccounts, isAccountingClassesEnabled, isUncategorizedExpenseCategoryEnabled, } = action.payload;
480
+ const { transactionId, lineId, updatedCustomer, selectedTransaction, selectedTab,
481
+ // uncategorizedAccounts, isAccountingClassesEnabled, and
482
+ // isUncategorizedExpenseCategoryEnabled remain in the payload type for
483
+ // backward compatibility but are no longer read here — the post-fetch
484
+ // success reducer (setEntityRecommendationForLineIdsForCategorization)
485
+ // owns the all-fields-filled check that drives auto-selection.
486
+ } = action.payload;
455
487
  const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
456
488
  .transactionReviewLocalDataById, transactionId, undefined);
457
489
  if (transactionLocalData != null) {
@@ -500,18 +532,13 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
500
532
  transactionReviewLocalData: newTransactionLocalData,
501
533
  transactionId,
502
534
  };
503
- const selectedCheckBoxTransactionIds = draft.transactionCategorizationView[selectedTab]
504
- .selectedCheckBoxTransactionIds;
505
- if (newTransactionLocalData.customer != null &&
506
- newTransactionLocalData.customer.id != null &&
507
- (0, transactionCategorizationLocalDataHelper_1.checkIfAllLineItemsAreCategoryClassFilled)(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
508
- selectedCheckBoxTransactionIds.length < transactionCategorizationLocalDataHelper_1.MAX_SELECTION_LIMIT &&
509
- selectedCheckBoxTransactionIds.includes(transactionId) === false) {
510
- draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
511
- ...selectedCheckBoxTransactionIds,
512
- transactionId,
513
- ];
514
- }
535
+ // Auto-selection of the row checkbox is intentionally deferred to
536
+ // setEntityRecommendationForLineIdsForCategorization (success path of
537
+ // the recommendations fetch). On a payee change the existing
538
+ // category/class are stale, so auto-selecting against them would
539
+ // either trigger save flows on the wrong data or rely on a later
540
+ // recommendations write to fix it. Letting the success reducer do the
541
+ // auto-add keeps "checkbox flips on" aligned with "fresh recs are in".
515
542
  // Mark transaction as dirty (customer updated)
516
543
  if (!draft.transactionCategorizationView[selectedTab].transactionIdsWithUnsavedData.includes(transactionId)) {
517
544
  draft.transactionCategorizationView[selectedTab].transactionIdsWithUnsavedData = [
@@ -523,7 +550,11 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
523
550
  }
524
551
  },
525
552
  updateSelectedVendorForTransaction(draft, action) {
526
- const { transactionId, lineId, updatedVendor, selectedTransaction, selectedTab, uncategorizedAccounts, isAccountingClassesEnabled, isUncategorizedExpenseCategoryEnabled, } = action.payload;
553
+ const { transactionId, lineId, updatedVendor, selectedTransaction, selectedTab,
554
+ // See updateSelectedCustomerForTransaction for why
555
+ // uncategorizedAccounts, isAccountingClassesEnabled, and
556
+ // isUncategorizedExpenseCategoryEnabled are no longer destructured.
557
+ } = action.payload;
527
558
  const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
528
559
  .transactionReviewLocalDataById, transactionId, undefined);
529
560
  if (transactionLocalData != null) {
@@ -576,18 +607,8 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
576
607
  },
577
608
  transactionId,
578
609
  };
579
- const selectedCheckBoxTransactionIds = draft.transactionCategorizationView[selectedTab]
580
- .selectedCheckBoxTransactionIds;
581
- if (newTransactionLocalData.vendor != null &&
582
- newTransactionLocalData.vendor.id != null &&
583
- (0, transactionCategorizationLocalDataHelper_1.checkIfAllLineItemsAreCategoryClassFilled)(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
584
- selectedCheckBoxTransactionIds.length < transactionCategorizationLocalDataHelper_1.MAX_SELECTION_LIMIT &&
585
- selectedCheckBoxTransactionIds.includes(transactionId) === false) {
586
- draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
587
- ...selectedCheckBoxTransactionIds,
588
- transactionId,
589
- ];
590
- }
610
+ // See updateSelectedCustomerForTransaction above for why auto-select
611
+ // is deferred to setEntityRecommendationForLineIdsForCategorization.
591
612
  // Mark transaction as dirty (vendor updated)
592
613
  if (!draft.transactionCategorizationView[selectedTab].transactionIdsWithUnsavedData.includes(transactionId)) {
593
614
  draft.transactionCategorizationView[selectedTab].transactionIdsWithUnsavedData = [
@@ -800,6 +821,54 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
800
821
  },
801
822
  },
802
823
  },
824
+ extraReducers: (builder) => {
825
+ // Start arm of the categorization-only recommendations fetch. Marks every
826
+ // affected line's per-line flag as In-Progress. The epic uses
827
+ // groupBy(transactionId+lineIds) + switchMap, so concurrent fetches for
828
+ // distinct (transaction, lineIds-set) targets do not cancel each other —
829
+ // there's no need for a global cleanup sweep here.
830
+ builder.addCase(recommendationReducer_1.fetchEntityRecommendationsForCategorization, (draft, action) => {
831
+ const { selectedTab, transactionDetails } = action.payload;
832
+ const { transactionId, lineIds } = transactionDetails;
833
+ const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
834
+ .transactionReviewLocalDataById, transactionId.id, undefined);
835
+ if (transactionLocalData != null) {
836
+ lineIds.forEach((lineId) => {
837
+ const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
838
+ if (lineItem != null) {
839
+ transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
840
+ ...lineItem,
841
+ categoryClassRecommendationsFetchState: {
842
+ fetchState: 'In-Progress',
843
+ error: undefined,
844
+ },
845
+ };
846
+ }
847
+ });
848
+ }
849
+ });
850
+ // Failure arm. Flips the affected lines' per-line flag to Error so the
851
+ // skeleton resolves and the queued checkbox re-evaluation drops the entry.
852
+ builder.addCase(recommendationReducer_1.setCategoryClassRecommendationsForCategorizationFailure, (draft, action) => {
853
+ const { selectedTab, transactionId, lineIds, error } = action.payload;
854
+ const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
855
+ .transactionReviewLocalDataById, transactionId.id, undefined);
856
+ if (transactionLocalData != null) {
857
+ lineIds.forEach((lineId) => {
858
+ const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
859
+ if (lineItem != null) {
860
+ transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
861
+ ...lineItem,
862
+ categoryClassRecommendationsFetchState: {
863
+ fetchState: 'Error',
864
+ error,
865
+ },
866
+ };
867
+ }
868
+ });
869
+ }
870
+ });
871
+ },
803
872
  });
804
873
  _a = expenseAutomationTransactionsView.actions, exports.fetchTransactionCategorization = _a.fetchTransactionCategorization, exports.updateTransactionCategorizationUIState = _a.updateTransactionCategorizationUIState, exports.initializeTransactionCategorizationViewLocalData = _a.initializeTransactionCategorizationViewLocalData, exports.saveTransactionCategorizationLocalData = _a.saveTransactionCategorizationLocalData, exports.fetchTransactionCategorizationFailure = _a.fetchTransactionCategorizationFailure, exports.saveTransactionCategorization = _a.saveTransactionCategorization, exports.updateTransactionCategorization = _a.updateTransactionCategorization, exports.updateCurrentSelectedTransactionCategorizationTab = _a.updateCurrentSelectedTransactionCategorizationTab, exports.updateTransactionCategorizationSaveStatus = _a.updateTransactionCategorizationSaveStatus, exports.markTransactionAsNotMiscategorized = _a.markTransactionAsNotMiscategorized, exports.updateStatusForTransactionNotMiscategorizedUpdateForCategorization = _a.updateStatusForTransactionNotMiscategorizedUpdateForCategorization, exports.updateSelectedVendorForTransaction = _a.updateSelectedVendorForTransaction, exports.updateSelectedCustomerForTransaction = _a.updateSelectedCustomerForTransaction, exports.setAllItemsToCategoryClassInLocalDataForCategorization = _a.setAllItemsToCategoryClassInLocalDataForCategorization, exports.updateTotalCountForTransactionCategorization = _a.updateTotalCountForTransactionCategorization, exports.fetchTransactionCategorizationSuccess = _a.fetchTransactionCategorizationSuccess, exports.resetOtherTabsFetchState = _a.resetOtherTabsFetchState, exports.fetchTransactionCategorizationView = _a.fetchTransactionCategorizationView, exports.updateSelectedCheckboxTransactionIds = _a.updateSelectedCheckboxTransactionIds, exports.clearExpenseAutomationTransactionsViewPerTabView = _a.clearExpenseAutomationTransactionsViewPerTabView, exports.clearExpenseAutomationTransactionsView = _a.clearExpenseAutomationTransactionsView, exports.setEntityRecommendationForLineIdsForCategorization = _a.setEntityRecommendationForLineIdsForCategorization, exports.updateSelectedTransactionId = _a.updateSelectedTransactionId, exports.syncTransactionCategorizationFromDetailSave = _a.syncTransactionCategorizationFromDetailSave, exports.backgroundRefetchReviewTab = _a.backgroundRefetchReviewTab, exports.updateTransactionCategorizationUploadReceiptState = _a.updateTransactionCategorizationUploadReceiptState, exports.uploadTransactionCategorizationReceiptSuccess = _a.uploadTransactionCategorizationReceiptSuccess;
805
874
  exports.default = expenseAutomationTransactionsView.reducer;
@@ -6,6 +6,7 @@ import { AccountBase } from '../../../entity/account/accountState';
6
6
  import { ClassBase } from '../../../entity/class/classState';
7
7
  import { SupportedTransactionWithCOT } from '../../../entity/transaction/transactionState';
8
8
  import { UncategorizedAccounts } from '../../accountList/accountListSelector';
9
+ import { ProjectListSelectorView } from '../../projectList/projectListSelector';
9
10
  import { TransactionReviewLocalData, TransactionsTab, TransactionsViewUIState } from '../types/transactionsViewState';
10
11
  export interface TransactionReviewLocalDataSelectorView {
11
12
  transactionId: ID;
@@ -18,7 +19,10 @@ export interface ExpenseAutomationTransactionViewSelector extends SelectorView {
18
19
  classList: ClassBase[];
19
20
  completionStatus: CompletionStatusType;
20
21
  fetchStateByTransactionTabs: Record<TransactionsTab, FetchStateAndError>;
22
+ hasInFlightCategoryClassRecommendations: boolean;
23
+ isAccountingProjectsEnabled: boolean;
21
24
  markAsNotMiscategorizedStatus: FetchStateAndError;
25
+ projectList: ProjectListSelectorView;
22
26
  refreshStatus: FetchStateAndError;
23
27
  saveStatus: FetchStateAndError;
24
28
  selectedCheckBoxTransactionIds: ID[];
@@ -12,9 +12,10 @@ const transactionHelper_1 = require("../../../entity/transaction/transactionHelp
12
12
  const transactionSelector_1 = require("../../../entity/transaction/transactionSelector");
13
13
  const accountListSelector_1 = require("../../accountList/accountListSelector");
14
14
  const classListSelector_1 = require("../../classList/classListSelector");
15
+ const projectListSelector_1 = require("../../projectList/projectListSelector");
15
16
  const expenseAutomationViewSelectorTypes_1 = require("../selectorTypes/expenseAutomationViewSelectorTypes");
16
17
  function getExpenseAutomationTransactionView(state) {
17
- const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
18
+ const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, projectState, projectListState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
18
19
  const { selectedTransactionCategorizationTab } = expenseAutomationTransactionsViewState;
19
20
  const { uiState, refreshStatus, saveStatus, markAsNotMiscategorizedStatus, transactionIdsBySelectedPeriod, transactionReviewLocalDataById, selectedCheckBoxTransactionIds, transactionIdsWithUnsavedData, uploadReceiptStatusById, selectedTransactionId, selectedTransactionLineId, } = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab];
20
21
  const uncategorizedIncomeExpense = (0, accountListSelector_1.getUncategorizedAccounts)(accountState, accountListState, 'accountList');
@@ -23,6 +24,8 @@ function getExpenseAutomationTransactionView(state) {
23
24
  const allClasses = classList.classes.map((classData) => {
24
25
  return (0, omit_1.default)(classData, ['accountIds', 'key']);
25
26
  });
27
+ const projectList = (0, projectListSelector_1.getProjectList)(projectState, projectListState);
28
+ const isAccountingProjectsEnabled = (0, tenantSelector_1.getIsAccountingProjectsEnabled)(state);
26
29
  const accountsHierarchyList = (0, accountListSelector_1.getNestedAccountListHierarchy)(accountListState, 'accountList');
27
30
  const classHierarchyList = (0, classListSelector_1.getNestedClassListHierarchy)(classListState);
28
31
  const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
@@ -45,6 +48,11 @@ function getExpenseAutomationTransactionView(state) {
45
48
  return null;
46
49
  })
47
50
  .filter((transaction) => transaction != null);
51
+ // True if any visible line is currently fetching category/class
52
+ // recommendations because the user changed the payee. Used to disable Save
53
+ // and to defer manual checkbox selection.
54
+ const hasInFlightCategoryClassRecommendations = transactionLocalData.some((transaction) => Object.values(transaction.transactionReviewLocalData.lineItemById).some((lineItem) => lineItem.categoryClassRecommendationsFetchState?.fetchState ===
55
+ 'In-Progress'));
48
56
  const transactions = (0, transactionSelector_1.getSupportedTransactionsByIds)(transactionState, transactionIds);
49
57
  const transactionsWithCOT = transactions.map((transaction) => (0, transactionHelper_1.getTransactionWithCOT)(transaction));
50
58
  const monthEndFetchState = monthYearPeriodId != null
@@ -102,6 +110,8 @@ function getExpenseAutomationTransactionView(state) {
102
110
  classList: allClasses,
103
111
  accountsHierarchyList,
104
112
  classHierarchyList,
113
+ isAccountingProjectsEnabled,
114
+ projectList,
105
115
  transactionLocalData,
106
116
  uiState,
107
117
  refreshStatus,
@@ -113,5 +123,6 @@ function getExpenseAutomationTransactionView(state) {
113
123
  uploadReceiptStatusById,
114
124
  selectedTransactionId,
115
125
  selectedTransactionLineId,
126
+ hasInFlightCategoryClassRecommendations,
116
127
  };
117
128
  }