@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
@@ -5,21 +5,26 @@ const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const responsePayload_1 = require("../../../responsePayload");
7
7
  const customerSummaryViewReducer_1 = require("../customerSummaryViewReducer");
8
+ const customerSummaryViewSelector_1 = require("../customerSummaryViewSelector");
8
9
  const fetchCustomerSummaryListEpic = (actions$, state$, zeniAPI) => {
9
10
  const fetch$ = actions$.pipe((0, operators_1.filter)(customerSummaryViewReducer_1.fetchCustomerSummaryList.match));
10
11
  const fetchPage = (action) => {
11
12
  const { keepExistingListItems, pageToken, searchString } = action.payload;
12
13
  const { uiState } = state$.value.customerSummaryViewState;
14
+ const settings = (0, customerSummaryViewSelector_1.getCustomersTabSettings)(state$.value);
13
15
  const query = {
14
16
  page_token: pageToken,
15
17
  sort_by: uiState.sortKey,
16
18
  sort_order: uiState.sortOrder === 'ascending' ? 'asc' : 'desc',
17
19
  search_text: searchString,
20
+ // Top-level only: a search also finds a customer by its sub-customers' and projects' names
21
+ top_level_only: settings.listTopLevelCustomersOnly,
22
+ include_sub_customers: settings.includeSubCustomersInTotals,
18
23
  };
19
24
  return zeniAPI
20
25
  .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/customers/summary?query=${encodeURIComponent(JSON.stringify(query))}`)
21
26
  .pipe((0, operators_1.map)((response) => (0, responsePayload_1.isSuccessResponse)(response)
22
- ? (0, customerSummaryViewReducer_1.updateCustomerSummaryList)(response, keepExistingListItems)
27
+ ? (0, customerSummaryViewReducer_1.updateCustomerSummaryList)(response, keepExistingListItems, settings)
23
28
  : (0, customerSummaryViewReducer_1.updateCustomerSummaryListFailure)(response.status)), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, customerSummaryViewReducer_1.updateCustomerSummaryListFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch customer summary list REST API call errored out' +
24
29
  JSON.stringify(error))))));
25
30
  };
@@ -39,7 +39,7 @@ export declare const getLineItemsByTransactionsIdsFromResponse: (transactions: S
39
39
  export declare const getLineItemsByTransactionIdsFromLocalData: (transactionLocalData: TransactionReviewLocalDataSelectorView[], selectedTab: TransactionsTab) => Record<ID, string[]>;
40
40
  export declare const mergeTabSpecificLineItems: (currentTabSpecificLineItems: TabSpecificLineItems, selectedTab: TransactionsTab, newLineItems: TabSpecificLineItems) => TabSpecificLineItems;
41
41
  export declare const getSnackbarMessageForTransactionReview: (updatedCount: number, failedCount: number, categorizedCount: number) => {
42
- messageSection: "common" | "recommendation_feedback" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "actual_matching_match_and_reverse" | "actual_matching_undo_reversal" | "actual_matching_ignore_suggestion" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "update_customer" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "revert_schedule" | "ignore_accrual" | "revert_accrual" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "create_transaction" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "accounting_projects_enabled_update" | "auto_review_income_without_customer_update" | "accounting_projects_qbo_not_enabled" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "confirm_statement_mapping" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron" | "create_sub_task" | "qbo_connection_already_linked" | "qbo_connection_failed" | "accounting_projects_qbo_reconnect_failed" | "product_services_update" | "qbo_realm_id_update" | "kyc_kyb_reset" | "invoicing_dunning_case_resolved" | "invoicing_dunning_retry" | "invoicing_dunning_cancel" | "invoicing_dunning_settings_save" | "invoicing_qbo_backfill" | "invoicing_qbo_sync_health_retry" | "invoicing_qbo_settings_save" | "invoicing_branding_save" | "invoicing_discount_archive" | "invoicing_discount_unarchive" | "invoicing_discount_delete" | "invoicing_invoice_reminder_sent" | "invoicing_invoice_regenerated" | "invoicing_invoice_voided" | "invoicing_catalog_item_saved" | "invoicing_customer_saved" | "invoicing_subscription_saved" | "invoicing_coupon_saved" | "invoicing_invoice_saved" | "invoicing_credit_note_saved" | "invoicing_payment_recorded" | "invoicing_subscription_activated" | "invoicing_subscription_cancellation_removed" | "invoicing_subscription_cancelled" | "invoicing_subscription_non_renewing" | "invoicing_subscription_paused" | "invoicing_subscription_reactivated" | "invoicing_subscription_resumed" | "invoicing_subscription_term_end_changed" | "invoicing_data_import_download";
42
+ messageSection: "common" | "recommendation_feedback" | "transactionDetails_updatingPastTransactions" | "transactionDetails_transactionUpdated" | "cockpit_month_end_email_sent" | "cockpit_month_end_email_save" | "cockpit_month_end_email_attachment_upload" | "je_bill_link" | "je_posted" | "actual_matching_match_and_reverse" | "actual_matching_undo_reversal" | "actual_matching_ignore_suggestion" | "audit_score_updated" | "people_invite_people" | "people_invite_multiple_people" | "people_delete_person" | "people_update_person" | "reimbursement_updated" | "reimbursement_deleted" | "reimbursement_cancelled_deleted" | "reimbursement_cancelled" | "reimbursement_approved" | "reimbursement_rejected" | "reimbursement_sent_for_approval" | "account_added" | "business_verification_save" | "business_verification_submit" | "business_verification_from_bills_submit" | "plaid_connection" | "unlink_deposit_account" | "reimbursement_setup" | "reimbursement_approval_create" | "reimbursement_duplicate_approval_create" | "reimbursement_approval_update" | "reimbursement_duplicate_approval_update" | "reimbursement_approval_delete" | "reimbursement_approval_reorder" | "reimbursement_create_mileage" | "reimbursement_update_mileage" | "reimbursement_accept_term" | "reimbursement_accept_employee_term" | "reimbursement_bulk_submit" | "reimbursement_bulk_processed" | "bill_pay_setup" | "zeni_accounts_setup" | "bill_pay_approval_create" | "bill_pay_duplicate_approval_create" | "bill_pay_approval_update" | "bill_pay_duplicate_approval_update" | "bill_pay_approval_delete" | "bill_pay_approval_reorder" | "bill_pay_updated" | "bill_pay_deleted" | "bill_pay_cancelled_deleted" | "bill_pay_cancelled" | "bill_pay_approved" | "real_time_approver_added" | "bill_pay_rejected" | "bill_pay_sent_for_approval" | "bill_pay_accept_term" | "bill_pay_bulk_submit" | "bill_pay_bulk_processed" | "bill_pay_refund" | "bill_pay_retry" | "bill_pay_marked_as_paid" | "zeni_account_accept_term" | "update_vendor" | "update_customer" | "data_refresh_update" | "delete_bank_account" | "create_bank_account" | "create_bank_account_ach" | "create_bank_account_wire" | "create_bank_account_international" | "transfer_money" | "update_zeni_account_nickname" | "create_checking_account" | "deposit_check" | "create_vendor" | "onboarding_customer_view" | "onboarding_customer_view_complete" | "onboarding_customer_identity_verification_save" | "onboarding_customer_identity_verification_submit" | "onboarding_customer_business_verification_save" | "onboarding_customer_business_verification_submit" | "retry_bank_account_connection" | "dashboard_invite_sent" | "onboarding_info_saved" | "approve_original_merchant" | "approve_global_merchant" | "reject_global_merchant" | "create_global_merchant" | "fetch_global_merchant_no_recommendation" | "save_vendor_renamed" | "save_vendor_sent_for_review" | "save_vendor_marked_as_employee" | "save_vendor_marked_as_local_contractor" | "charge_card_setup" | "charge_card_accept_term" | "charge_card_receipt_upload" | "charge_card_resend_invite" | "charge_card_revoke_invite" | "card_policy_created" | "card_policy_updated" | "card_policy_deleted" | "charge_card_update_limit" | "charge_cards_update_limit" | "close_charge_card" | "lock_charge_card" | "lock_charge_card_card_user" | "lock_charge_cards" | "unlock_charge_card" | "unlock_charge_card_card_user" | "unlock_charge_cards" | "close_charge_cards" | "revoke_invite_charge_cards" | "charge_card_express_interest" | "create_schedule" | "save_schedule" | "delete_schedule" | "ignore_schedule" | "revert_schedule" | "ignore_accrual" | "revert_accrual" | "save_task_detail" | "fetch_task_detail" | "delete_task" | "archive_task" | "snooze_task" | "unsnooze_task" | "create_tag" | "delete_tag" | "update_charge_card" | "update_charge_card_name" | "update_charge_card_name_card_user" | "issue_charge_card" | "issue_charge_cards" | "notification_settings_saved" | "referral_invite_sent" | "notification_mark_as_read" | "mark_as_complete_schedule" | "cancel_journal_entry" | "settings_accounting_accounts_updated" | "create_card_setup" | "confirm_card_setup" | "add_card_payment_source" | "fetch_payment_sources" | "task_assigned_toast_notification" | "task_due_tomorrow_toast_notification" | "task_deleted_toast_notification" | "task_archived_toast_notification" | "task_overdue_toast_notification" | "task_overdue_toast_notification_creator" | "task_notification_count" | "task_activities_toast_notification" | "task_created_toast_notification" | "task_group_creation_success" | "task_group_deletion_success" | "task_group_update_success" | "primary_funding_account_updated" | "task_time_spent_validation" | "missing_receipts_attachment" | "flux_analysis_unreviewed" | "flux_analysis_reviewed" | "receipt_match" | "receipts_upload" | "receipts_bulk_match" | "billing_address_view" | "express_pay_submit" | "exclude_transaction" | "reconcile" | "save_reconcile_for_later" | "recon_transaction_categorize" | "recon_transaction_match" | "update_debit_card_pin_attempt" | "set_debit_card_pin" | "ai_cfo_create_session_and_submit" | "ai_cfo_chat_session_deleted" | "charge_card_auto_pay_enable" | "charge_card_auto_pay_disable" | "treasury_setup" | "treasury_accept_term" | "treasury_transfer_money" | "treasury_transfer_money_failed" | "auto_transfer_rule_create" | "auto_transfer_rule_update" | "auto_transfer_rule_delete" | "auto_transfer_rule_pause" | "auto_transfer_rule_resume" | "treasury_update_portfolio_allocation" | "send_email_magic_link_to_user" | "complete_profile_done" | "create_transfer_entry" | "create_transaction" | "reports_resync" | "invalid_phone_number" | "transactions_categorized_updated_failed" | "transaction_categorized_updated_failed" | "transactionsCategorized_transactionsUpdated" | "transactionsCategorized_transactionUpdated" | "transactionCategorized_transactionsUpdated" | "transactionCategorized_transactionUpdated" | "transactionsCategorized_transactionsFailed" | "transactionsCategorized_transactionFailed" | "transactionCategorized_transactionsFailed" | "transactionCategorized_transactionFailed" | "transactionsUpdated_transactionsFailed" | "transactionsUpdated_transactionFailed" | "transactionUpdated_transactionsFailed" | "transactionUpdated_transactionFailed" | "transactionsCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionsUpdated_transactionFailed" | "transactionsCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionsUpdated_transactionsFailed" | "transactionsCategorized_transactionUpdated_transactionFailed" | "transactionCategorized_transactionsUpdated_transactionFailed" | "transactionCategorized_transactionUpdated_transactionsFailed" | "transactionCategorized_transactionUpdated_transactionFailed" | "accounting_classes_enabled_update" | "accounting_projects_enabled_update" | "auto_review_income_without_customer_update" | "customers_tab_settings_update" | "accounting_projects_qbo_not_enabled" | "capitalization_threshold_update" | "account_excluded_from_reconciliation" | "account_included_in_reconciliation" | "confirm_statement_mapping" | "statement_parsing_in_progress" | "statement_parsing_complete" | "ai_accountant_trigger_job" | "oauth_consent_approve" | "oauth_consent_invalid_request" | "credit_agent_update_profile" | "credit_agent_save_macro" | "credit_agent_schedule_cron" | "create_sub_task" | "qbo_connection_already_linked" | "qbo_connection_failed" | "accounting_projects_qbo_reconnect_failed" | "product_services_update" | "qbo_realm_id_update" | "kyc_kyb_reset" | "invoicing_dunning_case_resolved" | "invoicing_dunning_retry" | "invoicing_dunning_cancel" | "invoicing_dunning_settings_save" | "invoicing_qbo_backfill" | "invoicing_qbo_sync_health_retry" | "invoicing_qbo_settings_save" | "invoicing_branding_save" | "invoicing_discount_archive" | "invoicing_discount_unarchive" | "invoicing_discount_delete" | "invoicing_invoice_reminder_sent" | "invoicing_invoice_regenerated" | "invoicing_invoice_voided" | "invoicing_catalog_item_saved" | "invoicing_customer_saved" | "invoicing_subscription_saved" | "invoicing_coupon_saved" | "invoicing_invoice_saved" | "invoicing_credit_note_saved" | "invoicing_payment_recorded" | "invoicing_subscription_activated" | "invoicing_subscription_cancellation_removed" | "invoicing_subscription_cancelled" | "invoicing_subscription_non_renewing" | "invoicing_subscription_paused" | "invoicing_subscription_reactivated" | "invoicing_subscription_resumed" | "invoicing_subscription_term_end_changed" | "invoicing_data_import_download";
43
43
  messageText: "notification" | "failed" | "success";
44
44
  type: "error" | "success" | "info";
45
45
  variables: {
@@ -36,5 +36,13 @@ export interface FinanceStatementReport extends SelectorReport {
36
36
  selectedReportAndTimeframeFetchState: FetchStateAndError;
37
37
  selectedReportId: ReportID;
38
38
  dataAvailable?: DataAvailable;
39
+ /**
40
+ * Custom start/end the selected report (Accounts view only) was last fetched with for the
41
+ * selected timeframe; undefined when that fetch used the default periods.
42
+ */
43
+ selectedReportCustomDateRange?: {
44
+ endDate: string;
45
+ startDate: string;
46
+ };
39
47
  }
40
48
  export declare const getFinanceStatement: (state: RootState) => FinanceStatementReport;
@@ -164,6 +164,23 @@ exports.getFinanceStatement = (0, toolkit_1.createSelector)((state) => state.acc
164
164
  default:
165
165
  break;
166
166
  }
167
+ let customDateRangeByTimeframe;
168
+ switch (financeStatementState.selectedReportId) {
169
+ case 'profit_and_loss':
170
+ customDateRangeByTimeframe =
171
+ profitAndLossState.pandL.customDateRangeByTimeframe;
172
+ break;
173
+ case 'balance_sheet':
174
+ customDateRangeByTimeframe =
175
+ balanceSheetState.customDateRangeByTimeframe;
176
+ break;
177
+ case 'cash_flow':
178
+ customDateRangeByTimeframe = cashFlowState.customDateRangeByTimeframe;
179
+ break;
180
+ default:
181
+ break;
182
+ }
183
+ const selectedReportCustomDateRange = customDateRangeByTimeframe?.[financeStatementState.timeframe];
167
184
  return {
168
185
  reportId: 'finance_statement',
169
186
  reportTitle: '',
@@ -173,6 +190,7 @@ exports.getFinanceStatement = (0, toolkit_1.createSelector)((state) => state.acc
173
190
  allTimeframeTicks,
174
191
  balancesInTimeframe,
175
192
  selectedReportAndTimeframeFetchState,
193
+ selectedReportCustomDateRange,
176
194
  displayOrder: financeStatementState.displayOrder,
177
195
  reportFormat: financeStatementState.reportFormat,
178
196
  firstMonthOfFY,
@@ -10,7 +10,11 @@ const reportIdUniqueKey = (forecastId) => forecastId != null
10
10
  ? `profit_and_loss+${forecastId}`
11
11
  : 'profit_and_loss';
12
12
  exports.reportIdUniqueKey = reportIdUniqueKey;
13
- const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(profitAndLossReducer_1.fetchProfitAndLossForTimeframe.match), (0, operators_1.mergeMap)((action) => {
13
+ const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(profitAndLossReducer_1.fetchProfitAndLossForTimeframe.match),
14
+ // One stream per timeframe: a newer request for the same timeframe (e.g. a
15
+ // custom-date-range change, or a dated fetch right after a default one)
16
+ // cancels the older in-flight request so a stale response can't land last.
17
+ (0, operators_1.groupBy)((action) => `${action.payload.forecastId ?? ''}_${action.payload.timeframe}`), (0, operators_1.mergeMap)((group$) => group$.pipe((0, operators_1.switchMap)((action) => {
14
18
  const getTimeSeriesGroup = (timeframe) => {
15
19
  switch (timeframe) {
16
20
  case 'month':
@@ -29,7 +33,8 @@ const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pi
29
33
  queryValue.forecast_id = action.payload.forecastId;
30
34
  queryValue.is_forecast_vs_actual = true;
31
35
  }
32
- if (action.payload.startDate != null && action.payload.endDate != null) {
36
+ if (action.payload.startDate != null &&
37
+ action.payload.endDate != null) {
33
38
  queryValue.custom_start_date = action.payload.startDate;
34
39
  queryValue.custom_end_date = action.payload.endDate;
35
40
  }
@@ -59,5 +64,5 @@ const fetchProfitAndLossForTimeframeEpic = (actions$, _, zeniAPI) => actions$.pi
59
64
  return (0, rxjs_1.of)((0, profitAndLossReducer_1.updateProfitAndLossForTimeframeFailure)(response.status, action.payload.forecastId, action.payload.timeframe));
60
65
  }
61
66
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, profitAndLossReducer_1.updateProfitAndLossForTimeframeFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'P&L REST API call errored out' + JSON.stringify(error)), action.payload.forecastId, action.payload.timeframe))));
62
- }));
67
+ }))));
63
68
  exports.fetchProfitAndLossForTimeframeEpic = fetchProfitAndLossForTimeframeEpic;
@@ -5,6 +5,7 @@ exports.resetProfitAndLossNodeCollapseState = exports.updateProfitAndLossUIState
5
5
  exports.getState = getState;
6
6
  const toolkit_1 = require("@reduxjs/toolkit");
7
7
  const viewAndReportPayloadv2_1 = require("../../commonPayloadTypes/v2/viewAndReportPayloadv2");
8
+ const coaBalance_1 = require("../../commonStateTypes/coaBalance/coaBalance");
8
9
  const rootActions_1 = require("../../rootActions");
9
10
  exports.initialPandLState = {
10
11
  bookCloseDate: undefined,
@@ -76,7 +77,10 @@ const profitAndLoss = (0, toolkit_1.createSlice)({
76
77
  fetchState: 'In-Progress',
77
78
  error: undefined,
78
79
  };
79
- updateState(draft, action.payload.forecastId, { fetchState });
80
+ updateState(draft, action.payload.forecastId, {
81
+ fetchState,
82
+ customDateRangeByTimeframe: (0, coaBalance_1.withFetchedCustomDateRange)(pAndLState.customDateRangeByTimeframe, timeframe, action.payload.startDate, action.payload.endDate),
83
+ });
80
84
  },
81
85
  },
82
86
  updateProfitAndLossForTimeframe(draft, action) {
@@ -1,4 +1,4 @@
1
- import { FetchStateByTimeframe } from '../../commonStateTypes/coaBalance/coaBalance';
1
+ import { CustomDateRangeByTimeframe, FetchStateByTimeframe } from '../../commonStateTypes/coaBalance/coaBalance';
2
2
  import { ID } from '../../commonStateTypes/common';
3
3
  import { Report } from '../../commonStateTypes/viewAndReport/viewAndReport';
4
4
  export interface ProfitAndLossUIState {
@@ -11,6 +11,7 @@ export interface ProfitAndLossUIState {
11
11
  export interface ProfitAndLossState extends Report {
12
12
  fetchState: FetchStateByTimeframe;
13
13
  uiState: ProfitAndLossUIState;
14
+ customDateRangeByTimeframe?: CustomDateRangeByTimeframe;
14
15
  forecastId?: ID;
15
16
  }
16
17
  export interface ProfitAndLossWithForecastState {
@@ -69,7 +69,10 @@ export declare const fetchEditRemiDetailPage: import("@reduxjs/toolkit").ActionC
69
69
  reimbursementId?: ID;
70
70
  }, "editRemiView/currencyConversionValueSuccessOrFailure">, waitForRemiDetailThenInitializeLocalStore: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[reimbursementId: string], {
71
71
  reimbursementId: string;
72
- }, "editRemiView/waitForRemiDetailThenInitializeLocalStore", never, never>, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[lineId: string, reimbursementId?: string | undefined, merchantId?: string | undefined, merchantName?: string | undefined], {
72
+ }, "editRemiView/waitForRemiDetailThenInitializeLocalStore", never, never>, initializeRemiToLocalStoreFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[reimbursementId: string, error?: ZeniAPIStatus<Record<string, unknown>> | undefined], {
73
+ reimbursementId: string;
74
+ error: ZeniAPIStatus<Record<string, unknown>> | undefined;
75
+ }, "editRemiView/initializeRemiToLocalStoreFailure", never, never>, waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[lineId: string, reimbursementId?: string | undefined, merchantId?: string | undefined, merchantName?: string | undefined], {
73
76
  lineId: string;
74
77
  reimbursementId: string | undefined;
75
78
  merchantId: string | undefined;
@@ -77,7 +80,9 @@ export declare const fetchEditRemiDetailPage: import("@reduxjs/toolkit").ActionC
77
80
  }, "editRemiView/waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant", never, never>, updateAddRemiAutoFields: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
78
81
  addRemiAutoFields: Record<ID, AutoFields>;
79
82
  reimbursementId?: ID;
80
- }, "editRemiView/updateAddRemiAutoFields">, indicateReadyToInitializeRemiLocalStore: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"editRemiView/indicateReadyToInitializeRemiLocalStore">, updateUploadFetchState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
83
+ }, "editRemiView/updateAddRemiAutoFields">, indicateReadyToInitializeRemiLocalStore: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[reimbursementId: string], {
84
+ reimbursementId: string;
85
+ }, "editRemiView/indicateReadyToInitializeRemiLocalStore", never, never>, updateUploadFetchState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
81
86
  fetchState: FetchState;
82
87
  reimbursementId?: ID;
83
88
  }, "editRemiView/updateUploadFetchState">, updateRecommendationInMerchant: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.clearAddRemiAutoFields = exports.clearTentativeMerchantName = exports.updateTentativeMerchantNames = exports.updateRecommendationInMerchant = exports.updateUploadFetchState = exports.indicateReadyToInitializeRemiLocalStore = exports.updateAddRemiAutoFields = exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = exports.waitForRemiDetailThenInitializeLocalStore = exports.currencyConversionValueSuccessOrFailure = exports.updateHomeCurrencyConversion = exports.updateReimbursementType = exports.fetchCurrencyConversionValue = exports.parseReceiptsToRemi = exports.saveRemiSuccessOrFailure = exports.saveRemiDetail = exports.removeFileFromRemiUpdatesInLocalStore = exports.discardRemiUpdatesInLocalStore = exports.updatesPaymentToInLocalStore = exports.saveRemiUpdatesToLocalStore = exports.fetchRecommendationsAndUpdateMerchantRecommendations = exports.initializeRemiToLocalStore = exports.fetchRemiAndInitializeLocalStore = exports.fetchEditRemiDetailPage = exports.initialState = void 0;
4
+ exports.clearAddRemiAutoFields = exports.clearTentativeMerchantName = exports.updateTentativeMerchantNames = exports.updateRecommendationInMerchant = exports.updateUploadFetchState = exports.indicateReadyToInitializeRemiLocalStore = exports.updateAddRemiAutoFields = exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = exports.initializeRemiToLocalStoreFailure = exports.waitForRemiDetailThenInitializeLocalStore = exports.currencyConversionValueSuccessOrFailure = exports.updateHomeCurrencyConversion = exports.updateReimbursementType = exports.fetchCurrencyConversionValue = exports.parseReceiptsToRemi = exports.saveRemiSuccessOrFailure = exports.saveRemiDetail = exports.removeFileFromRemiUpdatesInLocalStore = exports.discardRemiUpdatesInLocalStore = exports.updatesPaymentToInLocalStore = exports.saveRemiUpdatesToLocalStore = exports.fetchRecommendationsAndUpdateMerchantRecommendations = exports.initializeRemiToLocalStore = exports.fetchRemiAndInitializeLocalStore = exports.fetchEditRemiDetailPage = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const amount_1 = require("../../../../commonStateTypes/amount");
7
7
  const rootActions_1 = require("../../../../rootActions");
@@ -34,8 +34,13 @@ const editRemiView = (0, toolkit_1.createSlice)({
34
34
  };
35
35
  },
36
36
  },
37
- indicateReadyToInitializeRemiLocalStore() {
38
- // do nothing
37
+ indicateReadyToInitializeRemiLocalStore: {
38
+ reducer() {
39
+ // do nothing
40
+ },
41
+ prepare(reimbursementId) {
42
+ return { payload: { reimbursementId } };
43
+ },
39
44
  },
40
45
  fetchRecommendationsAndUpdateMerchantRecommendations: {
41
46
  reducer() {
@@ -141,6 +146,21 @@ const editRemiView = (0, toolkit_1.createSlice)({
141
146
  return { payload: { reimbursementId } };
142
147
  },
143
148
  },
149
+ initializeRemiToLocalStoreFailure: {
150
+ reducer(draft, action) {
151
+ const { reimbursementId, error } = action.payload;
152
+ draft.editRemiStateById[reimbursementId] = {
153
+ ...draft.editRemiStateById[reimbursementId],
154
+ fetchStatus: {
155
+ fetchState: 'Error',
156
+ error,
157
+ },
158
+ };
159
+ },
160
+ prepare(reimbursementId, error) {
161
+ return { payload: { reimbursementId, error } };
162
+ },
163
+ },
144
164
  saveRemiUpdatesToLocalStore(draft, action) {
145
165
  if (action.payload.reimbursementId != null) {
146
166
  const reimbursementId = action.payload.reimbursementId;
@@ -391,7 +411,7 @@ const editRemiView = (0, toolkit_1.createSlice)({
391
411
  });
392
412
  },
393
413
  });
394
- _a = editRemiView.actions, exports.fetchEditRemiDetailPage = _a.fetchEditRemiDetailPage, exports.fetchRemiAndInitializeLocalStore = _a.fetchRemiAndInitializeLocalStore, exports.initializeRemiToLocalStore = _a.initializeRemiToLocalStore, exports.fetchRecommendationsAndUpdateMerchantRecommendations = _a.fetchRecommendationsAndUpdateMerchantRecommendations, exports.saveRemiUpdatesToLocalStore = _a.saveRemiUpdatesToLocalStore, exports.updatesPaymentToInLocalStore = _a.updatesPaymentToInLocalStore, exports.discardRemiUpdatesInLocalStore = _a.discardRemiUpdatesInLocalStore, exports.removeFileFromRemiUpdatesInLocalStore = _a.removeFileFromRemiUpdatesInLocalStore, exports.saveRemiDetail = _a.saveRemiDetail, exports.saveRemiSuccessOrFailure = _a.saveRemiSuccessOrFailure, exports.parseReceiptsToRemi = _a.parseReceiptsToRemi, exports.fetchCurrencyConversionValue = _a.fetchCurrencyConversionValue, exports.updateReimbursementType = _a.updateReimbursementType, exports.updateHomeCurrencyConversion = _a.updateHomeCurrencyConversion, exports.currencyConversionValueSuccessOrFailure = _a.currencyConversionValueSuccessOrFailure, exports.waitForRemiDetailThenInitializeLocalStore = _a.waitForRemiDetailThenInitializeLocalStore, exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = _a.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, exports.updateAddRemiAutoFields = _a.updateAddRemiAutoFields, exports.indicateReadyToInitializeRemiLocalStore = _a.indicateReadyToInitializeRemiLocalStore, exports.updateUploadFetchState = _a.updateUploadFetchState, exports.updateRecommendationInMerchant = _a.updateRecommendationInMerchant, exports.updateTentativeMerchantNames = _a.updateTentativeMerchantNames, exports.clearTentativeMerchantName = _a.clearTentativeMerchantName, exports.clearAddRemiAutoFields = _a.clearAddRemiAutoFields;
414
+ _a = editRemiView.actions, exports.fetchEditRemiDetailPage = _a.fetchEditRemiDetailPage, exports.fetchRemiAndInitializeLocalStore = _a.fetchRemiAndInitializeLocalStore, exports.initializeRemiToLocalStore = _a.initializeRemiToLocalStore, exports.fetchRecommendationsAndUpdateMerchantRecommendations = _a.fetchRecommendationsAndUpdateMerchantRecommendations, exports.saveRemiUpdatesToLocalStore = _a.saveRemiUpdatesToLocalStore, exports.updatesPaymentToInLocalStore = _a.updatesPaymentToInLocalStore, exports.discardRemiUpdatesInLocalStore = _a.discardRemiUpdatesInLocalStore, exports.removeFileFromRemiUpdatesInLocalStore = _a.removeFileFromRemiUpdatesInLocalStore, exports.saveRemiDetail = _a.saveRemiDetail, exports.saveRemiSuccessOrFailure = _a.saveRemiSuccessOrFailure, exports.parseReceiptsToRemi = _a.parseReceiptsToRemi, exports.fetchCurrencyConversionValue = _a.fetchCurrencyConversionValue, exports.updateReimbursementType = _a.updateReimbursementType, exports.updateHomeCurrencyConversion = _a.updateHomeCurrencyConversion, exports.currencyConversionValueSuccessOrFailure = _a.currencyConversionValueSuccessOrFailure, exports.waitForRemiDetailThenInitializeLocalStore = _a.waitForRemiDetailThenInitializeLocalStore, exports.initializeRemiToLocalStoreFailure = _a.initializeRemiToLocalStoreFailure, exports.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant = _a.waitForMerchantRecommendationFetchThenUpdateRecommendationInMerchant, exports.updateAddRemiAutoFields = _a.updateAddRemiAutoFields, exports.indicateReadyToInitializeRemiLocalStore = _a.indicateReadyToInitializeRemiLocalStore, exports.updateUploadFetchState = _a.updateUploadFetchState, exports.updateRecommendationInMerchant = _a.updateRecommendationInMerchant, exports.updateTentativeMerchantNames = _a.updateTentativeMerchantNames, exports.clearTentativeMerchantName = _a.clearTentativeMerchantName, exports.clearAddRemiAutoFields = _a.clearAddRemiAutoFields;
395
415
  exports.default = editRemiView.reducer;
396
416
  const doUpdateRecommendationForEntity = (draft, lineId, recommendations, shouldAutofill, reimbursementId, reimbursementStageCode) => {
397
417
  if (reimbursementId != null) {
@@ -1,6 +1,9 @@
1
1
  import { ActionsObservable, StateObservable } from 'redux-observable';
2
+ import { Observable } from 'rxjs';
3
+ import { clearAll } from '../../../../../rootActions';
2
4
  import { RootState } from '../../../../../rootStateTypes';
3
- import { fetchRemiDetail, updateRemiDetail } from '../../remiDetailView/remiDetailViewReducer';
4
- import { fetchRemiAndInitializeLocalStore, initializeRemiToLocalStore, waitForRemiDetailThenInitializeLocalStore } from '../editRemiViewReducer';
5
- export type ActionType = ReturnType<typeof waitForRemiDetailThenInitializeLocalStore> | ReturnType<typeof fetchRemiDetail> | ReturnType<typeof updateRemiDetail> | ReturnType<typeof initializeRemiToLocalStore> | ReturnType<typeof fetchRemiAndInitializeLocalStore>;
6
- export declare const fetchRemiAndInitializeLocalStoreEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => import("rxjs").Observable<ActionType>;
5
+ import { fetchRemiDetail, updateRemiDetail, updateRemiDetailFetchState } from '../../remiDetailView/remiDetailViewReducer';
6
+ import { fetchRemiAndInitializeLocalStore, indicateReadyToInitializeRemiLocalStore, initializeRemiToLocalStore, initializeRemiToLocalStoreFailure, waitForRemiDetailThenInitializeLocalStore } from '../editRemiViewReducer';
7
+ export type ActionType = ReturnType<typeof waitForRemiDetailThenInitializeLocalStore> | ReturnType<typeof fetchRemiDetail> | ReturnType<typeof updateRemiDetail> | ReturnType<typeof updateRemiDetailFetchState> | ReturnType<typeof initializeRemiToLocalStore> | ReturnType<typeof fetchRemiAndInitializeLocalStore> | ReturnType<typeof indicateReadyToInitializeRemiLocalStore> | ReturnType<typeof initializeRemiToLocalStoreFailure> | ReturnType<typeof clearAll>;
8
+ export declare const fetchRemiAndInitializeLocalStoreEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>) => Observable<ActionType>;
9
+ export declare const waitForRemiDetailThenInitializeLocalStoreEpic: (actions$: ActionsObservable<ActionType>) => Observable<ActionType>;
@@ -3,10 +3,11 @@ 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.fetchRemiAndInitializeLocalStoreEpic = void 0;
6
+ exports.waitForRemiDetailThenInitializeLocalStoreEpic = exports.fetchRemiAndInitializeLocalStoreEpic = void 0;
7
7
  const get_1 = __importDefault(require("lodash/get"));
8
8
  const rxjs_1 = require("rxjs");
9
9
  const operators_1 = require("rxjs/operators");
10
+ const rootActions_1 = require("../../../../../rootActions");
10
11
  const remiDetailViewReducer_1 = require("../../remiDetailView/remiDetailViewReducer");
11
12
  const editRemiViewReducer_1 = require("../editRemiViewReducer");
12
13
  const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => actions$.pipe((0, operators_1.filter)(editRemiViewReducer_1.fetchRemiAndInitializeLocalStore.match), (0, operators_1.mergeMap)((action) => {
@@ -42,3 +43,16 @@ const fetchRemiAndInitializeLocalStoreEpic = (actions$, state$) => actions$.pipe
42
43
  return (0, rxjs_1.from)(remiDetailActions);
43
44
  }));
44
45
  exports.fetchRemiAndInitializeLocalStoreEpic = fetchRemiAndInitializeLocalStoreEpic;
46
+ const waitForRemiDetailThenInitializeLocalStoreEpic = (actions$) => actions$.pipe((0, operators_1.filter)(editRemiViewReducer_1.waitForRemiDetailThenInitializeLocalStore.match), (0, operators_1.mergeMap)((action) => {
47
+ const { reimbursementId } = action.payload;
48
+ const ready$ = actions$.pipe((0, operators_1.filter)(editRemiViewReducer_1.indicateReadyToInitializeRemiLocalStore.match), (0, operators_1.filter)((readyAction) => readyAction.payload.reimbursementId === reimbursementId), (0, operators_1.take)(1), (0, operators_1.map)(() => (0, editRemiViewReducer_1.initializeRemiToLocalStore)(reimbursementId)));
49
+ const failed$ = actions$.pipe((0, operators_1.filter)(remiDetailViewReducer_1.updateRemiDetailFetchState.match), (0, operators_1.filter)((fetchStateAction) => fetchStateAction.payload.reimbursementId === reimbursementId &&
50
+ fetchStateAction.payload.fetchState === 'Error'), (0, operators_1.map)((fetchStateAction) => (0, editRemiViewReducer_1.initializeRemiToLocalStoreFailure)(reimbursementId, fetchStateAction.payload.error)));
51
+ const supersededOrCleared$ = actions$.pipe((0, operators_1.filter)((nextAction) => rootActions_1.clearAll.match(nextAction) ||
52
+ (editRemiViewReducer_1.waitForRemiDetailThenInitializeLocalStore.match(nextAction) &&
53
+ nextAction.payload.reimbursementId === reimbursementId)));
54
+ // An Error does not end the wait: a newer request for the same id may still succeed.
55
+ // After an Error, supersededOrCleared$ is what ends it.
56
+ return (0, rxjs_1.merge)(ready$, failed$).pipe((0, operators_1.takeWhile)((resultAction) => !editRemiViewReducer_1.initializeRemiToLocalStore.match(resultAction), true), (0, operators_1.takeUntil)(supersededOrCleared$));
57
+ }));
58
+ exports.waitForRemiDetailThenInitializeLocalStoreEpic = waitForRemiDetailThenInitializeLocalStoreEpic;
@@ -81,7 +81,7 @@ const fetchRemiDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, ope
81
81
  }));
82
82
  }
83
83
  });
84
- actions.push((0, editRemiViewReducer_1.indicateReadyToInitializeRemiLocalStore)()); // add dummy action
84
+ actions.push((0, editRemiViewReducer_1.indicateReadyToInitializeRemiLocalStore)(reimbursementId));
85
85
  if (response.data.transaction?.lines != null &&
86
86
  response.data.transaction.lines.length > 0) {
87
87
  actions.push((0, remiDetailViewReducer_1.fetchDuplicateReimbursement)(response.data.transaction.created_by_user_id, false, response.data.transaction.transaction_id));
@@ -55,15 +55,11 @@ const createTransactionEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, o
55
55
  // the working copy on unmount instead.
56
56
  // Before the local-data init: it seeds the detail entry that init writes into.
57
57
  (0, transactionDetailReducer_1.createTransactionSuccessOrFailure)('Completed', newTransactionId),
58
+ // No success snackbar here: the screen raises it once pending attachments upload.
58
59
  (0, transactionDetailReducer_1.initializeTransactionDetailLocalData)({
59
60
  transactionId: newTransactionId,
60
61
  vendorId: created.vendor_id ?? undefined,
61
62
  }),
62
- (0, snackbarReducer_1.openSnackbar)({
63
- messageSection: 'create_transaction',
64
- messageText: 'success',
65
- type: 'success',
66
- }),
67
63
  ]);
68
64
  }), (0, operators_1.catchError)((error) => {
69
65
  const message = error instanceof createTransactionPayload_1.UnresolvedCreateTransactionIdError
@@ -8,6 +8,7 @@ const get_1 = __importDefault(require("lodash/get"));
8
8
  const rxjs_1 = require("rxjs");
9
9
  const operators_1 = require("rxjs/operators");
10
10
  const timePeriod_1 = require("../../commonStateTypes/timePeriod");
11
+ const customerWithSubCustomersId_1 = require("../../entity/genericEntity/customerWithSubCustomersId");
11
12
  const transactionReducer_1 = require("../../entity/transaction/transactionReducer");
12
13
  const responsePayload_1 = require("../../responsePayload");
13
14
  const transactionListReducer_1 = require("./transactionListReducer");
@@ -19,12 +20,20 @@ const fetchTransactionListByEntityEpic = (actions$, state$, zeniAPI) => actions$
19
20
  if (action.payload.cacheOverride === true ||
20
21
  entityTransactions == null ||
21
22
  entityTransactions.hasValidState() === false) {
23
+ // Customers tab rolled-up view: cached under its own id, sent as the customer id plus the flag
24
+ const { customerId: entityId, includeSubCustomers } = action.payload.entity.type === 'customer'
25
+ ? (0, customerWithSubCustomersId_1.fromCustomerEntityId)(action.payload.entity.id)
26
+ : {
27
+ customerId: action.payload.entity.id,
28
+ includeSubCustomers: false,
29
+ };
22
30
  const queryParam = {
23
31
  start_date: (0, timePeriod_1.toString)(action.payload.period.start),
24
32
  end_date: (0, timePeriod_1.toString)(action.payload.period.end),
25
33
  sort_by: 'create_time',
26
34
  sort_order: 'desc',
27
- entity_id: action.payload.entity.id,
35
+ entity_id: entityId,
36
+ ...(includeSubCustomers ? { include_sub_customers: true } : {}),
28
37
  entity_name: action.payload.entity.name,
29
38
  entity_type: action.payload.entity.type,
30
39
  is_fetch_all_transactions: action.payload.isFetchAllTransactions === true
@@ -37,7 +46,7 @@ const fetchTransactionListByEntityEpic = (actions$, state$, zeniAPI) => actions$
37
46
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
38
47
  const updateActions = [];
39
48
  updateActions.push((0, transactionReducer_1.updateTransactions)(response.data.transactions, (value) => value.transaction_id));
40
- updateActions.push((0, transactionListReducer_1.updateTransactionListByEntity)(response.data));
49
+ updateActions.push((0, transactionListReducer_1.updateTransactionListByEntity)(response.data, action.payload.entity.id));
41
50
  return (0, rxjs_1.from)(updateActions);
42
51
  }
43
52
  else {
@@ -0,0 +1,15 @@
1
+ import { TimePeriod } from '../../commonStateTypes/timePeriod';
2
+ import { ZeniDate } from '../../zeniDayJS';
3
+ /**
4
+ * Transaction lists are fetched and cached in month buckets: `splitPeriod`
5
+ * snaps the first bucket back to the 1st of the month, while the last bucket
6
+ * is fetched with the real end date. So a period that starts mid-month (e.g. a
7
+ * drill-down from the custom-date-range column "Jun 17-30 2026") pulls in the
8
+ * days before its start. Drop those so the list reconciles to the clicked
9
+ * figure. Periods starting on the 1st (every pre-existing caller) are returned
10
+ * untouched. Compares calendar days as `YYYY-MM-DD` strings so the viewer's
11
+ * timezone can't shift the boundary.
12
+ */
13
+ export declare const filterTransactionsByTimePeriod: <T extends {
14
+ date: ZeniDate;
15
+ }>(transactions: T[], period: TimePeriod) => T[];
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterTransactionsByTimePeriod = void 0;
4
+ const timePeriod_1 = require("../../commonStateTypes/timePeriod");
5
+ /**
6
+ * Transaction lists are fetched and cached in month buckets: `splitPeriod`
7
+ * snaps the first bucket back to the 1st of the month, while the last bucket
8
+ * is fetched with the real end date. So a period that starts mid-month (e.g. a
9
+ * drill-down from the custom-date-range column "Jun 17-30 2026") pulls in the
10
+ * days before its start. Drop those so the list reconciles to the clicked
11
+ * figure. Periods starting on the 1st (every pre-existing caller) are returned
12
+ * untouched. Compares calendar days as `YYYY-MM-DD` strings so the viewer's
13
+ * timezone can't shift the boundary.
14
+ */
15
+ const filterTransactionsByTimePeriod = (transactions, period) => {
16
+ if (period.start.day === 1) {
17
+ return transactions;
18
+ }
19
+ const start = (0, timePeriod_1.toString)(period.start);
20
+ return transactions.filter((transaction) => transaction.date.format(timePeriod_1.DEFAULT_DATE_FORMAT) >= start);
21
+ };
22
+ exports.filterTransactionsByTimePeriod = filterTransactionsByTimePeriod;
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
8
8
  const get_1 = __importDefault(require("lodash/get"));
9
9
  const orderBy_1 = __importDefault(require("lodash/orderBy"));
10
10
  const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
11
+ const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
11
12
  const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
12
13
  const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
13
14
  const transactionListState_1 = require("./transactionListState");
@@ -35,7 +36,7 @@ const getTransactionListByAccount = (transactionState, transactionListState, acc
35
36
  }
36
37
  return value != null;
37
38
  });
38
- transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
39
+ transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
39
40
  }
40
41
  const key = (0, transactionListState_1.getAcKey)(accountId, accountType);
41
42
  const uiState = (0, get_1.default)(transactionListState.byAccount.transactionListUIStateByAccountKey, key, {});
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
8
8
  const get_1 = __importDefault(require("lodash/get"));
9
9
  const orderBy_1 = __importDefault(require("lodash/orderBy"));
10
10
  const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
11
+ const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
11
12
  const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
12
13
  const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
13
14
  const transactionListState_1 = require("./transactionListState");
@@ -32,7 +33,7 @@ const getTransactionsListByCategoryType = (transactionState, transactionListStat
32
33
  }
33
34
  return value != null;
34
35
  });
35
- transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
36
+ transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
36
37
  }
37
38
  const uiState = transactionListState.byType[transactionCategoryType].transactionListUIState;
38
39
  return {
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
8
8
  const get_1 = __importDefault(require("lodash/get"));
9
9
  const orderBy_1 = __importDefault(require("lodash/orderBy"));
10
10
  const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
11
+ const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
11
12
  const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
12
13
  const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
13
14
  const transactionListState_1 = require("./transactionListState");
@@ -35,7 +36,7 @@ const getTransactionListByClass = (transactionState, transactionListState, accou
35
36
  }
36
37
  return value != null;
37
38
  });
38
- transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
39
+ transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
39
40
  }
40
41
  const key = (0, transactionListState_1.getClassAcKey)(accountId, accountType, classId);
41
42
  const uiState = (0, get_1.default)(transactionListState.byClass.transactionListUIStateByClassKey, key, {});
@@ -8,6 +8,7 @@ const flatMap_1 = __importDefault(require("lodash/flatMap"));
8
8
  const get_1 = __importDefault(require("lodash/get"));
9
9
  const orderBy_1 = __importDefault(require("lodash/orderBy"));
10
10
  const transactionSelector_1 = require("../../entity/transaction/transactionSelector");
11
+ const filterTransactionsByTimePeriod_1 = require("./filterTransactionsByTimePeriod");
11
12
  const parallelFetchAccountTransactionListEpic_1 = require("./parallelFetchAccountTransactionListEpic");
12
13
  const reduceTransactionListFetchState_1 = require("./reduceTransactionListFetchState");
13
14
  const transactionListState_1 = require("./transactionListState");
@@ -35,7 +36,7 @@ const getTransactionListByProject = (transactionState, transactionListState, acc
35
36
  }
36
37
  return value != null;
37
38
  });
38
- transactions = (0, orderBy_1.default)(transactionsUnsorted, (value) => value.date.valueOf(), 'desc');
39
+ transactions = (0, orderBy_1.default)((0, filterTransactionsByTimePeriod_1.filterTransactionsByTimePeriod)(transactionsUnsorted, filterByTimePeriod), (value) => value.date.valueOf(), 'desc');
39
40
  }
40
41
  const key = (0, transactionListState_1.getProjectAcKey)(accountId, accountType, projectId);
41
42
  const uiState = (0, get_1.default)(transactionListState.byProject.transactionListUIStateByProjectKey, key, {});
@@ -38,7 +38,9 @@ export declare const parallelFetchAccountTransactionList: import("@reduxjs/toolk
38
38
  period: TimePeriod;
39
39
  cacheOverride: any;
40
40
  isFetchAllTransactions: any;
41
- }, "transactionList/fetchEntityTransactionList", never, never>, updateTransactionListByEntity: import("@reduxjs/toolkit").ActionCreatorWithPayload<TransactionListByEntityPayload, "transactionList/updateTransactionListByEntity">, updateTransactionListByEntityFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[entity: Entity, period: TimePeriod, error: ZeniAPIStatus<Record<string, unknown>>], {
41
+ }, "transactionList/fetchEntityTransactionList", never, never>, updateTransactionListByEntity: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: TransactionListByEntityPayload, entityId?: string | undefined], TransactionListByEntityPayload, "transactionList/updateTransactionListByEntity", never, {
42
+ entityId: string | undefined;
43
+ }>, updateTransactionListByEntityFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[entity: Entity, period: TimePeriod, error: ZeniAPIStatus<Record<string, unknown>>], {
42
44
  entity: Entity;
43
45
  period: TimePeriod;
44
46
  error: ZeniAPIStatus<Record<string, unknown>>;
@@ -168,21 +168,30 @@ const transactionList = (0, toolkit_1.createSlice)({
168
168
  };
169
169
  },
170
170
  },
171
- updateTransactionListByEntity(draft, action) {
172
- const transactionIDs = action.payload.transactions.map((transactionPayload) => transactionPayload.transaction_id);
173
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
174
- const entity = mapTransactionQueryMetaDataToEntity(action.payload.query);
175
- const key = (0, transactionListState_1.getEntityTranKey)(entity, {
176
- start: (0, timePeriod_1.toAbsoluteDay)(action.payload.query.start_date),
177
- end: (0, timePeriod_1.toAbsoluteDay)(action.payload.query.end_date),
178
- });
179
- draft.byEntity.transactionListByEntityKey[key] = {
180
- ...transactionListState_1.initialEntityTransactionState,
181
- fetchState: 'Completed',
182
- error: undefined,
183
- entity: entity,
184
- transactionIDs,
185
- };
171
+ updateTransactionListByEntity: {
172
+ // `entityId`: the requested entity's id when it differs from the query's (a rolled-up customer)
173
+ prepare(payload, entityId) {
174
+ return { payload, meta: { entityId } };
175
+ },
176
+ reducer(draft, action) {
177
+ const transactionIDs = action.payload.transactions.map((transactionPayload) => transactionPayload.transaction_id);
178
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
179
+ const entity = {
180
+ ...mapTransactionQueryMetaDataToEntity(action.payload.query),
181
+ ...(action.meta.entityId != null && { id: action.meta.entityId }),
182
+ };
183
+ const key = (0, transactionListState_1.getEntityTranKey)(entity, {
184
+ start: (0, timePeriod_1.toAbsoluteDay)(action.payload.query.start_date),
185
+ end: (0, timePeriod_1.toAbsoluteDay)(action.payload.query.end_date),
186
+ });
187
+ draft.byEntity.transactionListByEntityKey[key] = {
188
+ ...transactionListState_1.initialEntityTransactionState,
189
+ fetchState: 'Completed',
190
+ error: undefined,
191
+ entity: entity,
192
+ transactionIDs,
193
+ };
194
+ },
186
195
  },
187
196
  updateTransactionListByEntityFailure: {
188
197
  reducer(draft, action) {
@@ -6,6 +6,7 @@ const operators_1 = require("rxjs/operators");
6
6
  const timeframeTick_1 = require("../../commonStateTypes/timeframeTick");
7
7
  const customerIncomeTrendKey_1 = require("../../entity/customerIncome/customerIncomeTrendKey");
8
8
  const customerIncomeTrendReducer_1 = require("../../entity/customerIncome/customerIncomeTrendReducer");
9
+ const customerWithSubCustomersId_1 = require("../../entity/genericEntity/customerWithSubCustomersId");
9
10
  const responsePayload_1 = require("../../responsePayload");
10
11
  const zeniDayJS_1 = require("../../zeniDayJS");
11
12
  const trendReducer_1 = require("./trendReducer");
@@ -28,11 +29,14 @@ const fetchIncomeTrendEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, op
28
29
  return (0, rxjs_1.of)((0, trendReducer_1.updateTrendSuccess)(requestedPeriod));
29
30
  }
30
31
  }
32
+ // The rolled-up view is cached under its own id; the API takes the customer id plus the flag
33
+ const { customerId: apiCustomerId, includeSubCustomers } = (0, customerWithSubCustomersId_1.fromCustomerEntityId)(customerId);
31
34
  const query = {
32
- entity_id: customerId,
35
+ entity_id: apiCustomerId,
33
36
  entity_type: 'customer',
34
- customer_id: customerId,
37
+ customer_id: apiCustomerId,
35
38
  customer_name: customerName,
39
+ ...(includeSubCustomers ? { include_sub_customers: true } : {}),
36
40
  ...(dateRange != null
37
41
  ? { start_date: dateRange.startDate, end_date: dateRange.endDate }
38
42
  : {}),