@zeniai/client-epic-state 5.2.83 → 5.2.85-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.
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/entity/transaction/stateTypes/paymentType.d.ts +2 -2
- package/lib/entity/transaction/stateTypes/paymentType.js +9 -1
- package/lib/entity/transaction/stateTypes/printStatus.d.ts +4 -0
- package/lib/entity/transaction/stateTypes/printStatus.js +11 -0
- package/lib/epic.d.ts +4 -1
- package/lib/epic.js +6 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/esm/entity/transaction/stateTypes/paymentType.js +9 -1
- package/lib/esm/entity/transaction/stateTypes/printStatus.js +7 -0
- package/lib/esm/epic.js +6 -0
- package/lib/esm/index.js +5 -2
- package/lib/esm/view/invoicing/createInvoice/epics/fetchCreateInvoiceFormPageEpic.js +19 -5
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.js +7 -4
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.js +3 -1
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionDetailPageEpic.js +7 -4
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionFormPageEpic.js +1 -0
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.js +2 -0
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +6 -2
- package/lib/esm/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.js +14 -3
- package/lib/esm/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.js +14 -3
- package/lib/esm/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewReducer.js +2 -0
- package/lib/esm/view/invoicing/invoicingListTabCache.js +8 -0
- package/lib/esm/view/transactionDetail/createTransaction/createTransactionLocalDataHelper.js +145 -0
- package/lib/esm/view/transactionDetail/createTransaction/createTransactionPayload.js +162 -0
- package/lib/esm/view/transactionDetail/createTransaction/createTransactionSelector.js +47 -0
- package/lib/esm/view/transactionDetail/createTransaction/createTransactionState.js +11 -0
- package/lib/esm/view/transactionDetail/createTransaction/epics/createTransactionEpic.js +80 -0
- package/lib/esm/view/transactionDetail/createTransaction/epics/fetchVendorRecommendationsForCreateTransactionEpic.js +53 -0
- package/lib/esm/view/transactionDetail/createTransaction/epics/initializeCreateTransactionLocalDataEpic.js +14 -0
- package/lib/esm/view/transactionDetail/transactionDetailReducer.js +176 -1
- package/lib/index.d.ts +6 -2
- package/lib/index.js +57 -37
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/invoicing/createInvoice/epics/fetchCreateInvoiceFormPageEpic.js +18 -4
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.d.ts +1 -1
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewPayload.js +7 -4
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.d.ts +2 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/editInvoicingSubscriptionDetailViewSelector.js +2 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionDetailPageEpic.js +6 -3
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/fetchInvoicingSubscriptionFormPageEpic.js +1 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.d.ts +2 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.js +4 -1
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +5 -1
- package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.js +14 -3
- package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.js +14 -3
- package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewReducer.d.ts +6 -0
- package/lib/view/invoicing/invoicingCatalogListView/invoicingCatalogListViewReducer.js +2 -0
- package/lib/view/invoicing/invoicingListTabCache.d.ts +11 -1
- package/lib/view/invoicing/invoicingListTabCache.js +10 -1
- package/lib/view/transactionDetail/createTransaction/createTransactionLocalDataHelper.d.ts +52 -0
- package/lib/view/transactionDetail/createTransaction/createTransactionLocalDataHelper.js +160 -0
- package/lib/view/transactionDetail/createTransaction/createTransactionPayload.d.ts +95 -0
- package/lib/view/transactionDetail/createTransaction/createTransactionPayload.js +167 -0
- package/lib/view/transactionDetail/createTransaction/createTransactionSelector.d.ts +44 -0
- package/lib/view/transactionDetail/createTransaction/createTransactionSelector.js +53 -0
- package/lib/view/transactionDetail/createTransaction/createTransactionState.d.ts +82 -0
- package/lib/view/transactionDetail/createTransaction/createTransactionState.js +14 -0
- package/lib/view/transactionDetail/createTransaction/epics/createTransactionEpic.d.ts +9 -0
- package/lib/view/transactionDetail/createTransaction/epics/createTransactionEpic.js +84 -0
- package/lib/view/transactionDetail/createTransaction/epics/fetchVendorRecommendationsForCreateTransactionEpic.d.ts +20 -0
- package/lib/view/transactionDetail/createTransaction/epics/fetchVendorRecommendationsForCreateTransactionEpic.js +57 -0
- package/lib/view/transactionDetail/createTransaction/epics/initializeCreateTransactionLocalDataEpic.d.ts +12 -0
- package/lib/view/transactionDetail/createTransaction/epics/initializeCreateTransactionLocalDataEpic.js +18 -0
- package/lib/view/transactionDetail/transactionDetailReducer.d.ts +37 -1
- package/lib/view/transactionDetail/transactionDetailReducer.js +178 -2
- package/lib/view/transactionDetail/transactionDetailState.d.ts +12 -0
- package/package.json +1 -1
package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts
CHANGED
|
@@ -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" | "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" | "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" | "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" | "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" | "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: {
|
|
@@ -16,6 +16,8 @@ const createInvoiceReducer_1 = require("../createInvoiceReducer");
|
|
|
16
16
|
const shouldFetch = (fetchStateAndError, cacheOverride) => cacheOverride ||
|
|
17
17
|
(fetchStateAndError.fetchState !== 'Completed' &&
|
|
18
18
|
fetchStateAndError.fetchState !== 'In-Progress');
|
|
19
|
+
const PICKER_PLAN_FILTERS = { type: 'plan' };
|
|
20
|
+
const PICKER_PRODUCT_FILTERS = { type: 'addon|charge' };
|
|
19
21
|
/**
|
|
20
22
|
* Orchestrates the create-invoice form's option sources: on
|
|
21
23
|
* `fetchCreateInvoiceFormPage`, fans out to the customer, catalog plan, catalog
|
|
@@ -37,15 +39,27 @@ const fetchCreateInvoiceFormPageEpic = (actions$, state$) => actions$.pipe((0, o
|
|
|
37
39
|
tabId: invoicingListTabCache_1.INVOICING_LIST_ALL_TAB,
|
|
38
40
|
}));
|
|
39
41
|
}
|
|
40
|
-
if (
|
|
42
|
+
if ((0, invoicingListTabCache_1.shouldFetchFullInvoicingList)({
|
|
43
|
+
fetchState: catalogState.fetchState,
|
|
44
|
+
filters: catalogState.planFilters,
|
|
45
|
+
nextCursor: catalogState.planNextCursor,
|
|
46
|
+
sort: catalogState.planSort,
|
|
47
|
+
}, PICKER_PLAN_FILTERS, cacheOverride)) {
|
|
41
48
|
pageActions.push((0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogPlanList)({
|
|
42
|
-
|
|
49
|
+
fetchAll: true,
|
|
50
|
+
filters: PICKER_PLAN_FILTERS,
|
|
43
51
|
keepExistingListItems: false,
|
|
44
52
|
}));
|
|
45
53
|
}
|
|
46
|
-
if (
|
|
54
|
+
if ((0, invoicingListTabCache_1.shouldFetchFullInvoicingList)({
|
|
55
|
+
fetchState: catalogState.productFetchState.fetchState,
|
|
56
|
+
filters: catalogState.productFilters,
|
|
57
|
+
nextCursor: catalogState.productNextCursor,
|
|
58
|
+
sort: catalogState.productSort,
|
|
59
|
+
}, PICKER_PRODUCT_FILTERS, cacheOverride)) {
|
|
47
60
|
pageActions.push((0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogProductList)({
|
|
48
|
-
|
|
61
|
+
fetchAll: true,
|
|
62
|
+
filters: PICKER_PRODUCT_FILTERS,
|
|
49
63
|
keepExistingListItems: false,
|
|
50
64
|
}));
|
|
51
65
|
}
|
|
@@ -18,7 +18,7 @@ export type SaveInvoicingSubscriptionResponse = ZeniAPIResponse<InvoicingSubscri
|
|
|
18
18
|
* Sending them made every price point whose cadence the form could not express
|
|
19
19
|
* — a daily plan, for instance — fail with a 422.
|
|
20
20
|
*/
|
|
21
|
-
export declare const localDataToSaveInvoicingSubscriptionPayload: (localData: InvoicingSubscriptionFormLocalData, shippingAddress?: AddressUpdatableInfo) => Record<string, unknown>;
|
|
21
|
+
export declare const localDataToSaveInvoicingSubscriptionPayload: (localData: InvoicingSubscriptionFormLocalData, shippingAddress?: AddressUpdatableInfo, flatFeePriceCodes?: ReadonlySet<string>) => Record<string, unknown>;
|
|
22
22
|
export type RunInvoicingSubscriptionActionResponse = ZeniAPIResponse<InvoicingSubscriptionPayload>;
|
|
23
23
|
/** Snake_case request bodies for subscription action endpoints. */
|
|
24
24
|
export type ApplyCouponBody = {
|
|
@@ -20,22 +20,25 @@ const invoicingSubscriptionFormConfig_1 = require("./invoicingSubscriptionFormCo
|
|
|
20
20
|
* Sending them made every price point whose cadence the form could not express
|
|
21
21
|
* — a daily plan, for instance — fail with a 422.
|
|
22
22
|
*/
|
|
23
|
-
const localDataToSaveInvoicingSubscriptionPayload = (localData, shippingAddress) => {
|
|
23
|
+
const localDataToSaveInvoicingSubscriptionPayload = (localData, shippingAddress, flatFeePriceCodes = new Set()) => {
|
|
24
|
+
const itemQuantity = (priceCode, quantity) => flatFeePriceCodes.has(priceCode)
|
|
25
|
+
? 1
|
|
26
|
+
: (0, invoicingSubscriptionFormConfig_1.toInvoicingSubscriptionQuantity)(quantity);
|
|
24
27
|
const items = [
|
|
25
28
|
{
|
|
26
29
|
item_price_code: localData.planPriceCode,
|
|
27
30
|
item_type: 'plan',
|
|
28
|
-
quantity: (
|
|
31
|
+
quantity: itemQuantity(localData.planPriceCode, localData.planQuantity),
|
|
29
32
|
},
|
|
30
33
|
...localData.addonPriceCodes.map((priceCode) => ({
|
|
31
34
|
item_price_code: priceCode,
|
|
32
35
|
item_type: 'addon',
|
|
33
|
-
quantity: (
|
|
36
|
+
quantity: itemQuantity(priceCode, localData.addonQuantities[priceCode]),
|
|
34
37
|
})),
|
|
35
38
|
...localData.chargePriceCodes.map((priceCode) => ({
|
|
36
39
|
item_price_code: priceCode,
|
|
37
40
|
item_type: 'charge',
|
|
38
|
-
quantity: (
|
|
41
|
+
quantity: itemQuantity(priceCode, localData.chargeQuantities[priceCode]),
|
|
39
42
|
})),
|
|
40
43
|
];
|
|
41
44
|
const setupFee = localData.setupFee?.amount;
|
|
@@ -147,6 +147,8 @@ export interface InvoicingSubscriptionOption {
|
|
|
147
147
|
billingCycles?: number;
|
|
148
148
|
billingPeriod?: number;
|
|
149
149
|
billingPeriodUnit?: string;
|
|
150
|
+
/** Catalog options only: false for a flat fee, which takes no quantity. */
|
|
151
|
+
hasQuantity?: boolean;
|
|
150
152
|
price?: Amount;
|
|
151
153
|
productCode?: string;
|
|
152
154
|
subtitle?: string;
|
|
@@ -182,6 +182,7 @@ const toInvoicingPlanOption = (plan) => ({
|
|
|
182
182
|
// price point and rejects a subscription that claims a different one.
|
|
183
183
|
billingPeriod: plan.period,
|
|
184
184
|
billingPeriodUnit: plan.periodUnit,
|
|
185
|
+
hasQuantity: (0, invoicingSubscriptionFormConfig_1.invoicingPriceHasQuantity)(plan.pricingModel),
|
|
185
186
|
label: plan.name ?? plan.id,
|
|
186
187
|
price: invoicingUnitPrice(plan),
|
|
187
188
|
productCode: plan.productCode,
|
|
@@ -193,6 +194,7 @@ const toInvoicingCatalogItemOption = (product) => ({
|
|
|
193
194
|
// A one-time charge has no cadence, so its price is quoted flat rather than
|
|
194
195
|
// per period.
|
|
195
196
|
billingPeriodUnit: product.itemType === 'charge' ? undefined : product.periodUnit,
|
|
197
|
+
hasQuantity: (0, invoicingSubscriptionFormConfig_1.invoicingPriceHasQuantity)(product.pricingModel),
|
|
196
198
|
label: product.name ?? product.id,
|
|
197
199
|
price: invoicingUnitPrice(product),
|
|
198
200
|
productCode: product.productCode,
|
|
@@ -43,11 +43,14 @@ const fetchInvoicingSubscriptionDetailPageEpic = (actions$, state$) => actions$.
|
|
|
43
43
|
// Plan and coupon lists back the names the page renders for its line
|
|
44
44
|
// items; both list slices cache, so this only refetches when asked to.
|
|
45
45
|
const catalogListState = state.invoicingCatalogListViewState;
|
|
46
|
-
if (
|
|
47
|
-
error: catalogListState.error,
|
|
46
|
+
if ((0, invoicingListTabCache_1.shouldFetchFullInvoicingList)({
|
|
48
47
|
fetchState: catalogListState.fetchState,
|
|
49
|
-
|
|
48
|
+
filters: catalogListState.planFilters,
|
|
49
|
+
nextCursor: catalogListState.planNextCursor,
|
|
50
|
+
sort: catalogListState.planSort,
|
|
51
|
+
}, { type: 'plan' }, cacheOverride)) {
|
|
50
52
|
pageActions.push((0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogPlanList)({
|
|
53
|
+
fetchAll: true,
|
|
51
54
|
filters: { type: 'plan' },
|
|
52
55
|
keepExistingListItems: false,
|
|
53
56
|
}));
|
|
@@ -23,6 +23,7 @@ const fetchInvoicingSubscriptionFormPageEpic = (actions$) => actions$.pipe((0, o
|
|
|
23
23
|
// unfiltered list would replace the store's plans with every catalog
|
|
24
24
|
// item.
|
|
25
25
|
(0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogPlanList)({
|
|
26
|
+
fetchAll: true,
|
|
26
27
|
filters: { type: 'plan' },
|
|
27
28
|
keepExistingListItems: false,
|
|
28
29
|
}),
|
package/lib/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export declare const INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE: "invoicing_su
|
|
|
8
8
|
* their day gets their own calendar date rather than yesterday's.
|
|
9
9
|
*/
|
|
10
10
|
export declare const invoicingSubscriptionTodayIso: () => string;
|
|
11
|
+
/** A flat fee bills its price once, so its quantity is always 1. */
|
|
12
|
+
export declare const invoicingPriceHasQuantity: (pricingModel?: string) => boolean;
|
|
11
13
|
/**
|
|
12
14
|
* Clamp a subscription-item quantity to the minimum the API accepts. Shared by
|
|
13
15
|
* the plan, add-on and charge items so none of them can bill a 0 or a fraction.
|
package/lib/view/invoicing/editInvoicingSubscriptionDetailView/invoicingSubscriptionFormConfig.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.entityToInvoicingSubscriptionFormLocalData = exports.initialInvoicingSubscriptionFormLocalData = exports.toInvoicingSubscriptionBillingCycles = exports.toInvoicingSubscriptionQuantity = exports.invoicingSubscriptionTodayIso = exports.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE = void 0;
|
|
3
|
+
exports.entityToInvoicingSubscriptionFormLocalData = exports.initialInvoicingSubscriptionFormLocalData = exports.toInvoicingSubscriptionBillingCycles = exports.toInvoicingSubscriptionQuantity = exports.invoicingPriceHasQuantity = exports.invoicingSubscriptionTodayIso = exports.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE = void 0;
|
|
4
4
|
const zeniDayJS_1 = require("../../../zeniDayJS");
|
|
5
5
|
/** `AddressType` key used when the subscription form opens the shared Address screen. */
|
|
6
6
|
exports.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE = 'invoicing_subscription_shipping_address';
|
|
@@ -26,6 +26,9 @@ const subscriptionItemQuantities = (subscription, itemType) => {
|
|
|
26
26
|
*/
|
|
27
27
|
const invoicingSubscriptionTodayIso = () => (0, zeniDayJS_1.dateNow)().format('YYYY-MM-DD');
|
|
28
28
|
exports.invoicingSubscriptionTodayIso = invoicingSubscriptionTodayIso;
|
|
29
|
+
/** A flat fee bills its price once, so its quantity is always 1. */
|
|
30
|
+
const invoicingPriceHasQuantity = (pricingModel) => pricingModel !== 'flat_fee';
|
|
31
|
+
exports.invoicingPriceHasQuantity = invoicingPriceHasQuantity;
|
|
29
32
|
/**
|
|
30
33
|
* Clamp a subscription-item quantity to the minimum the API accepts. Shared by
|
|
31
34
|
* the plan, add-on and charge items so none of them can bill a 0 or a fraction.
|
package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js
CHANGED
|
@@ -12,6 +12,7 @@ const responsePayload_1 = require("../../../responsePayload");
|
|
|
12
12
|
const addressViewReducer_1 = require("../../addressView/addressViewReducer");
|
|
13
13
|
const editInvoicingCustomerDetailViewReducer_1 = require("../editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer");
|
|
14
14
|
const invoiceListReducer_1 = require("../invoiceList/invoiceListReducer");
|
|
15
|
+
const invoicingCatalogListViewSelector_1 = require("../invoicingCatalogListView/invoicingCatalogListViewSelector");
|
|
15
16
|
const invoicingSubscriptionListViewReducer_1 = require("../invoicingSubscriptionListView/invoicingSubscriptionListViewReducer");
|
|
16
17
|
const editInvoicingSubscriptionDetailViewPayload_1 = require("./editInvoicingSubscriptionDetailViewPayload");
|
|
17
18
|
const editInvoicingSubscriptionDetailViewReducer_1 = require("./editInvoicingSubscriptionDetailViewReducer");
|
|
@@ -29,7 +30,10 @@ const invoicingSubscriptionSaveRequest = (rootState, id) => {
|
|
|
29
30
|
// Shipping address captured via the shared Address screen is sent as an
|
|
30
31
|
// object in the payload (same pattern as the customer save flow).
|
|
31
32
|
const shippingAddress = rootState.addressViewState.newAddressState?.[invoicingSubscriptionFormConfig_1.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE]?.addressToCreate;
|
|
32
|
-
const
|
|
33
|
+
const flatFeePriceCodes = new Set((0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(Object.values(rootState.invoicingCatalogState.itemByID))
|
|
34
|
+
.filter((price) => !(0, invoicingSubscriptionFormConfig_1.invoicingPriceHasQuantity)(price.pricingModel))
|
|
35
|
+
.flatMap((price) => price.priceCode ?? []));
|
|
36
|
+
const data = (0, editInvoicingSubscriptionDetailViewPayload_1.localDataToSaveInvoicingSubscriptionPayload)(localData, shippingAddress, flatFeePriceCodes);
|
|
33
37
|
if (id != null) {
|
|
34
38
|
delete data.coupon_ids;
|
|
35
39
|
}
|
package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogPlanListEpic.js
CHANGED
|
@@ -26,19 +26,30 @@ const buildPlanQuery = (filters, cursor, sort) => {
|
|
|
26
26
|
return params;
|
|
27
27
|
};
|
|
28
28
|
const fetchInvoicingCatalogPlanListEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(invoicingCatalogListViewReducer_1.fetchInvoicingCatalogPlanList.match), (0, operators_1.switchMap)((action) => {
|
|
29
|
-
const { filters, cursor, keepExistingListItems, sort } = action.payload;
|
|
29
|
+
const { filters, cursor, fetchAll, keepExistingListItems, sort } = action.payload;
|
|
30
30
|
const apiUrl = (0, invoicingApiHelper_1.withQuery)(`${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/catalog/plans`, buildPlanQuery(filters, cursor, sort));
|
|
31
31
|
return zeniAPI.getJSON(apiUrl).pipe((0, operators_1.switchMap)((response) => {
|
|
32
32
|
if ((0, responsePayload_1.isSuccessResponse)(response)) {
|
|
33
33
|
const items = response.data?.items ?? [];
|
|
34
|
-
|
|
34
|
+
const nextCursor = response.data?.next_cursor ?? null;
|
|
35
|
+
const pageActions = [
|
|
35
36
|
(0, invoicingCatalogReducer_1.updateInvoicingCatalogItems)(items, 'merge'),
|
|
36
37
|
(0, invoicingCatalogListViewReducer_1.updateInvoicingCatalogPlanList)({
|
|
37
38
|
ids: items.map((item) => item.id),
|
|
38
|
-
nextCursor
|
|
39
|
+
nextCursor,
|
|
39
40
|
keepExistingListItems,
|
|
40
41
|
}),
|
|
41
42
|
];
|
|
43
|
+
if (fetchAll && nextCursor != null && nextCursor !== cursor) {
|
|
44
|
+
pageActions.push((0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogPlanList)({
|
|
45
|
+
cursor: nextCursor,
|
|
46
|
+
fetchAll,
|
|
47
|
+
filters,
|
|
48
|
+
keepExistingListItems: true,
|
|
49
|
+
sort,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
return pageActions;
|
|
42
53
|
}
|
|
43
54
|
return (0, rxjs_1.of)((0, invoicingCatalogListViewReducer_1.updateInvoicingCatalogPlanListFailure)(response.status));
|
|
44
55
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, invoicingCatalogListViewReducer_1.updateInvoicingCatalogPlanListFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch catalog plan list REST API call errored out ' +
|
package/lib/view/invoicing/invoicingCatalogListView/epics/fetchInvoicingCatalogProductListEpic.js
CHANGED
|
@@ -26,19 +26,30 @@ const buildProductQuery = (filters, cursor, sort) => {
|
|
|
26
26
|
return params;
|
|
27
27
|
};
|
|
28
28
|
const fetchInvoicingCatalogProductListEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(invoicingCatalogListViewReducer_1.fetchInvoicingCatalogProductList.match), (0, operators_1.switchMap)((action) => {
|
|
29
|
-
const { filters, cursor, keepExistingListItems, sort } = action.payload;
|
|
29
|
+
const { filters, cursor, fetchAll, keepExistingListItems, sort } = action.payload;
|
|
30
30
|
const apiUrl = (0, invoicingApiHelper_1.withQuery)(`${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/catalog/plans`, buildProductQuery(filters, cursor, sort));
|
|
31
31
|
return zeniAPI.getJSON(apiUrl).pipe((0, operators_1.switchMap)((response) => {
|
|
32
32
|
if ((0, responsePayload_1.isSuccessResponse)(response)) {
|
|
33
33
|
const items = response.data?.items ?? [];
|
|
34
|
-
|
|
34
|
+
const nextCursor = response.data?.next_cursor ?? null;
|
|
35
|
+
const pageActions = [
|
|
35
36
|
(0, invoicingCatalogReducer_1.updateInvoicingCatalogItems)(items, 'merge'),
|
|
36
37
|
(0, invoicingCatalogListViewReducer_1.updateInvoicingCatalogProductList)({
|
|
37
38
|
ids: items.map((item) => item.id),
|
|
38
|
-
nextCursor
|
|
39
|
+
nextCursor,
|
|
39
40
|
keepExistingListItems,
|
|
40
41
|
}),
|
|
41
42
|
];
|
|
43
|
+
if (fetchAll && nextCursor != null && nextCursor !== cursor) {
|
|
44
|
+
pageActions.push((0, invoicingCatalogListViewReducer_1.fetchInvoicingCatalogProductList)({
|
|
45
|
+
cursor: nextCursor,
|
|
46
|
+
fetchAll,
|
|
47
|
+
filters,
|
|
48
|
+
keepExistingListItems: true,
|
|
49
|
+
sort,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
return pageActions;
|
|
42
53
|
}
|
|
43
54
|
return (0, rxjs_1.of)((0, invoicingCatalogListViewReducer_1.updateInvoicingCatalogProductListFailure)(response.status));
|
|
44
55
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, invoicingCatalogListViewReducer_1.updateInvoicingCatalogProductListFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch catalog product list REST API call errored out ' +
|
|
@@ -6,12 +6,15 @@ import { InvoicingCatalogListViewState, InvoicingCatalogPlanFilters, InvoicingCa
|
|
|
6
6
|
export declare const initialState: InvoicingCatalogListViewState;
|
|
7
7
|
export declare const fetchInvoicingCatalogPlanList: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: {
|
|
8
8
|
cursor?: string;
|
|
9
|
+
/** Keep requesting the next page until the list is complete. */
|
|
10
|
+
fetchAll?: boolean;
|
|
9
11
|
filters?: InvoicingCatalogPlanFilters;
|
|
10
12
|
keepExistingListItems?: boolean;
|
|
11
13
|
sort?: InvoicingListSort;
|
|
12
14
|
}], {
|
|
13
15
|
filters: InvoicingCatalogPlanFilters;
|
|
14
16
|
cursor: string | undefined;
|
|
17
|
+
fetchAll: boolean;
|
|
15
18
|
keepExistingListItems: boolean;
|
|
16
19
|
sort: InvoicingListSort | undefined;
|
|
17
20
|
}, "invoicingCatalogListView/fetchInvoicingCatalogPlanList", never, never>, updateInvoicingCatalogPlanList: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
@@ -20,12 +23,15 @@ export declare const fetchInvoicingCatalogPlanList: import("@reduxjs/toolkit").A
|
|
|
20
23
|
nextCursor: string | null;
|
|
21
24
|
}, "invoicingCatalogListView/updateInvoicingCatalogPlanList">, updateInvoicingCatalogPlanListFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "invoicingCatalogListView/updateInvoicingCatalogPlanListFailure">, fetchInvoicingCatalogProductList: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: {
|
|
22
25
|
cursor?: string;
|
|
26
|
+
/** Keep requesting the next page until the list is complete. */
|
|
27
|
+
fetchAll?: boolean;
|
|
23
28
|
filters?: InvoicingCatalogProductFilters;
|
|
24
29
|
keepExistingListItems?: boolean;
|
|
25
30
|
sort?: InvoicingListSort;
|
|
26
31
|
}], {
|
|
27
32
|
filters: InvoicingCatalogProductFilters;
|
|
28
33
|
cursor: string | undefined;
|
|
34
|
+
fetchAll: boolean;
|
|
29
35
|
keepExistingListItems: boolean;
|
|
30
36
|
sort: InvoicingListSort | undefined;
|
|
31
37
|
}, "invoicingCatalogListView/fetchInvoicingCatalogProductList", never, never>, updateInvoicingCatalogProductList: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
@@ -40,6 +40,7 @@ const invoicingCatalogListView = (0, toolkit_1.createSlice)({
|
|
|
40
40
|
payload: {
|
|
41
41
|
filters: payload.filters ?? {},
|
|
42
42
|
cursor: payload.cursor,
|
|
43
|
+
fetchAll: payload.fetchAll ?? false,
|
|
43
44
|
keepExistingListItems: payload.keepExistingListItems ?? false,
|
|
44
45
|
sort: payload.sort,
|
|
45
46
|
},
|
|
@@ -74,6 +75,7 @@ const invoicingCatalogListView = (0, toolkit_1.createSlice)({
|
|
|
74
75
|
payload: {
|
|
75
76
|
filters: payload.filters ?? {},
|
|
76
77
|
cursor: payload.cursor,
|
|
78
|
+
fetchAll: payload.fetchAll ?? false,
|
|
77
79
|
keepExistingListItems: payload.keepExistingListItems ?? false,
|
|
78
80
|
sort: payload.sort,
|
|
79
81
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FetchStateAndError, ID } from '../../commonStateTypes/common';
|
|
1
|
+
import { FetchState, FetchStateAndError, ID } from '../../commonStateTypes/common';
|
|
2
2
|
import { ZeniAPIStatus } from '../../responsePayload';
|
|
3
3
|
import { InvoicingListSort } from './invoicingApiHelper';
|
|
4
4
|
/**
|
|
@@ -42,6 +42,16 @@ export declare const isSameInvoicingListQuery: (a: {
|
|
|
42
42
|
filters: object;
|
|
43
43
|
sort?: InvoicingListSort;
|
|
44
44
|
}) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* For a picker that searches client-side: reuse only a complete list fetched
|
|
47
|
+
* with the picker's own query, else load every page of it.
|
|
48
|
+
*/
|
|
49
|
+
export declare const shouldFetchFullInvoicingList: (list: {
|
|
50
|
+
fetchState: FetchState;
|
|
51
|
+
filters: object;
|
|
52
|
+
nextCursor: string | null;
|
|
53
|
+
sort?: InvoicingListSort;
|
|
54
|
+
}, pickerFilters: object, cacheOverride: boolean) => boolean;
|
|
45
55
|
/** What opening a tab should fetch, if anything. */
|
|
46
56
|
export type InvoicingListTabFetch = {
|
|
47
57
|
kind: 'none';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isSameInvoicingListQuery = exports.invoicingListStatusParam = exports.invoicingListFetchTab = exports.invoicingListSourceTab = exports.getInvoicingListTab = exports.INVOICING_LIST_ALL_TAB = void 0;
|
|
3
|
+
exports.shouldFetchFullInvoicingList = exports.isSameInvoicingListQuery = exports.invoicingListStatusParam = exports.invoicingListFetchTab = exports.invoicingListSourceTab = exports.getInvoicingListTab = exports.INVOICING_LIST_ALL_TAB = void 0;
|
|
4
4
|
exports.planInvoicingListTabFetch = planInvoicingListTabFetch;
|
|
5
5
|
exports.startInvoicingListTabFetch = startInvoicingListTabFetch;
|
|
6
6
|
exports.completeInvoicingListTabFetch = completeInvoicingListTabFetch;
|
|
@@ -46,6 +46,15 @@ const isSameInvoicingListQuery = (a, b) => {
|
|
|
46
46
|
a.sort?.dir === b.sort?.dir);
|
|
47
47
|
};
|
|
48
48
|
exports.isSameInvoicingListQuery = isSameInvoicingListQuery;
|
|
49
|
+
/**
|
|
50
|
+
* For a picker that searches client-side: reuse only a complete list fetched
|
|
51
|
+
* with the picker's own query, else load every page of it.
|
|
52
|
+
*/
|
|
53
|
+
const shouldFetchFullInvoicingList = (list, pickerFilters, cacheOverride) => cacheOverride ||
|
|
54
|
+
list.fetchState !== 'Completed' ||
|
|
55
|
+
list.nextCursor != null ||
|
|
56
|
+
!(0, exports.isSameInvoicingListQuery)({ filters: list.filters, sort: list.sort }, { filters: pickerFilters });
|
|
57
|
+
exports.shouldFetchFullInvoicingList = shouldFetchFullInvoicingList;
|
|
49
58
|
/**
|
|
50
59
|
* Fetch a tab that is empty or failed; top up one that holds less than a page
|
|
51
60
|
* while the server says there is more; leave a full or complete one cached.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Recommendation, RecommendationWithCOT } from '../../../commonStateTypes/recommendationBase';
|
|
2
|
+
import { TransactionCategory } from '../../../entity/transaction/stateTypes/transactionType';
|
|
3
|
+
import { CreatableTransactionType, CreateTransactionLineLocalData, CreateTransactionLocalData, CreateTransactionLocalDataByType } from './createTransactionState';
|
|
4
|
+
export declare const nextCreateTransactionLineId: () => string;
|
|
5
|
+
/** Test-only: makes line ids predictable from the start of each case. */
|
|
6
|
+
export declare const resetCreateTransactionLineIdCounter: () => void;
|
|
7
|
+
export declare const createEmptyCreateTransactionLine: (postingType?: TransactionCategory) => CreateTransactionLineLocalData;
|
|
8
|
+
/**
|
|
9
|
+
* The lines a freshly-opened form starts with. A journal entry is invalid with fewer than one
|
|
10
|
+
* debit and one credit, so it opens with both rather than making the user add the second row.
|
|
11
|
+
* Transfer has no lines at all.
|
|
12
|
+
*/
|
|
13
|
+
export declare const getDefaultCreateTransactionLines: (transactionType: CreatableTransactionType) => CreateTransactionLineLocalData[];
|
|
14
|
+
/**
|
|
15
|
+
* A blank working copy for one type. Note this does NOT seed the date -- the reducer's initial
|
|
16
|
+
* state has to stay a pure constant so `clearAll` restores something stable. The date is seeded
|
|
17
|
+
* by initializeCreateTransactionLocalDataEpic, which runs when the form opens.
|
|
18
|
+
*/
|
|
19
|
+
export declare const getEmptyCreateTransactionLocalData: (transactionType: CreatableTransactionType) => CreateTransactionLocalData;
|
|
20
|
+
export declare const getInitialCreateTransactionLocalDataByType: () => CreateTransactionLocalDataByType;
|
|
21
|
+
/**
|
|
22
|
+
* What the form opens with: a blank copy plus today's date, the default line set, and the
|
|
23
|
+
* payment_type the backend insists on for the type.
|
|
24
|
+
*/
|
|
25
|
+
export declare const getSeededCreateTransactionLocalData: (transactionType: CreatableTransactionType) => CreateTransactionLocalData;
|
|
26
|
+
/**
|
|
27
|
+
* Merges a partial edit into the working copy. Lines are replaced wholesale when present --
|
|
28
|
+
* a partial line array would silently truncate the form.
|
|
29
|
+
*/
|
|
30
|
+
export declare const mergeCreateTransactionLocalData: (current: CreateTransactionLocalData, update: Partial<CreateTransactionLocalData>) => CreateTransactionLocalData;
|
|
31
|
+
export declare const updateCreateTransactionLine: (lines: CreateTransactionLineLocalData[], lineId: string, update: Partial<CreateTransactionLineLocalData>) => CreateTransactionLineLocalData[];
|
|
32
|
+
/**
|
|
33
|
+
* Recommendation -> RecommendationWithCOT. Chain-of-thought and recommendation feedback both
|
|
34
|
+
* need an existing transaction, so cot/reasoning are empty here by design; the dropdown only
|
|
35
|
+
* needs the entities to build its "Recommended" group.
|
|
36
|
+
*/
|
|
37
|
+
export declare const toRecommendationsWithCOT: (recommendations: Recommendation[]) => RecommendationWithCOT[];
|
|
38
|
+
/**
|
|
39
|
+
* Applies a vendor's recommendations to one line: always refreshes the dropdown's "Recommended"
|
|
40
|
+
* group, but only prefills account/class when the field is still empty. Callers switching
|
|
41
|
+
* vendors clear the previous prefill first, so "empty" includes what the last vendor filled. Anything the user
|
|
42
|
+
* picked wins -- this follows the transaction-categorization helper, which prefills, rather
|
|
43
|
+
* than the detail-page helper, which only suggests.
|
|
44
|
+
*/
|
|
45
|
+
export declare const applyRecommendationsToCreateTransactionLine: (line: CreateTransactionLineLocalData, recommendations: Recommendation[], isAccountingClassesEnabled: boolean) => CreateTransactionLineLocalData;
|
|
46
|
+
/**
|
|
47
|
+
* Undoes a prefill when the vendor is cleared. Only the fields the prefill wrote are removed --
|
|
48
|
+
* the per-field flags are what make the user's own choices distinguishable from ours, which is
|
|
49
|
+
* why they are not a single line-level boolean: a hand-picked account alongside a prefilled
|
|
50
|
+
* class is an ordinary state, and clearing must not take the account with it.
|
|
51
|
+
*/
|
|
52
|
+
export declare const clearRecommendationsFromCreateTransactionLine: (line: CreateTransactionLineLocalData) => CreateTransactionLineLocalData;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clearRecommendationsFromCreateTransactionLine = exports.applyRecommendationsToCreateTransactionLine = exports.toRecommendationsWithCOT = exports.updateCreateTransactionLine = exports.mergeCreateTransactionLocalData = exports.getSeededCreateTransactionLocalData = exports.getInitialCreateTransactionLocalDataByType = exports.getEmptyCreateTransactionLocalData = exports.getDefaultCreateTransactionLines = exports.createEmptyCreateTransactionLine = exports.resetCreateTransactionLineIdCounter = exports.nextCreateTransactionLineId = void 0;
|
|
4
|
+
const zeniDayJS_1 = require("../../../zeniDayJS");
|
|
5
|
+
const createTransactionState_1 = require("./createTransactionState");
|
|
6
|
+
/**
|
|
7
|
+
* Monotonic counter for line row keys. These never leave the client -- the payload builder
|
|
8
|
+
* drops them -- so a counter is enough, and it keeps reducer tests deterministic in a way
|
|
9
|
+
* randomUUID would not.
|
|
10
|
+
*/
|
|
11
|
+
let lineIdCounter = 0;
|
|
12
|
+
const nextCreateTransactionLineId = () => `create-transaction-line-${lineIdCounter++}`;
|
|
13
|
+
exports.nextCreateTransactionLineId = nextCreateTransactionLineId;
|
|
14
|
+
/** Test-only: makes line ids predictable from the start of each case. */
|
|
15
|
+
const resetCreateTransactionLineIdCounter = () => {
|
|
16
|
+
lineIdCounter = 0;
|
|
17
|
+
};
|
|
18
|
+
exports.resetCreateTransactionLineIdCounter = resetCreateTransactionLineIdCounter;
|
|
19
|
+
const createEmptyCreateTransactionLine = (postingType) => ({
|
|
20
|
+
id: (0, exports.nextCreateTransactionLineId)(),
|
|
21
|
+
postingType,
|
|
22
|
+
});
|
|
23
|
+
exports.createEmptyCreateTransactionLine = createEmptyCreateTransactionLine;
|
|
24
|
+
/**
|
|
25
|
+
* The lines a freshly-opened form starts with. A journal entry is invalid with fewer than one
|
|
26
|
+
* debit and one credit, so it opens with both rather than making the user add the second row.
|
|
27
|
+
* Transfer has no lines at all.
|
|
28
|
+
*/
|
|
29
|
+
const getDefaultCreateTransactionLines = (transactionType) => {
|
|
30
|
+
if (transactionType === 'transfer') {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
if (transactionType === 'journal_entry') {
|
|
34
|
+
return [
|
|
35
|
+
(0, exports.createEmptyCreateTransactionLine)('debit'),
|
|
36
|
+
(0, exports.createEmptyCreateTransactionLine)('credit'),
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
return [(0, exports.createEmptyCreateTransactionLine)()];
|
|
40
|
+
};
|
|
41
|
+
exports.getDefaultCreateTransactionLines = getDefaultCreateTransactionLines;
|
|
42
|
+
/**
|
|
43
|
+
* A blank working copy for one type. Note this does NOT seed the date -- the reducer's initial
|
|
44
|
+
* state has to stay a pure constant so `clearAll` restores something stable. The date is seeded
|
|
45
|
+
* by initializeCreateTransactionLocalDataEpic, which runs when the form opens.
|
|
46
|
+
*/
|
|
47
|
+
const getEmptyCreateTransactionLocalData = (transactionType) => ({
|
|
48
|
+
lines: [],
|
|
49
|
+
transactionType,
|
|
50
|
+
});
|
|
51
|
+
exports.getEmptyCreateTransactionLocalData = getEmptyCreateTransactionLocalData;
|
|
52
|
+
const getInitialCreateTransactionLocalDataByType = () => createTransactionState_1.ALL_CREATABLE_TRANSACTION_TYPES.reduce((acc, transactionType) => {
|
|
53
|
+
acc[transactionType] =
|
|
54
|
+
(0, exports.getEmptyCreateTransactionLocalData)(transactionType);
|
|
55
|
+
return acc;
|
|
56
|
+
}, {});
|
|
57
|
+
exports.getInitialCreateTransactionLocalDataByType = getInitialCreateTransactionLocalDataByType;
|
|
58
|
+
/**
|
|
59
|
+
* The payment_type the backend insists on for some types: a check needs `check`, and a
|
|
60
|
+
* credit_card_credit (sent as expense + is_credit) needs a card type -- qbo_purchase.py raises
|
|
61
|
+
* without them.
|
|
62
|
+
*/
|
|
63
|
+
const SEEDED_PAYMENT_TYPE = {
|
|
64
|
+
check: 'check',
|
|
65
|
+
credit_card_credit: 'credit_card',
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* What the form opens with: a blank copy plus today's date, the default line set, and the
|
|
69
|
+
* payment_type the backend insists on for the type.
|
|
70
|
+
*/
|
|
71
|
+
const getSeededCreateTransactionLocalData = (transactionType) => ({
|
|
72
|
+
...(0, exports.getEmptyCreateTransactionLocalData)(transactionType),
|
|
73
|
+
lines: (0, exports.getDefaultCreateTransactionLines)(transactionType),
|
|
74
|
+
paymentType: SEEDED_PAYMENT_TYPE[transactionType],
|
|
75
|
+
transactionDate: (0, zeniDayJS_1.dateNow)(),
|
|
76
|
+
});
|
|
77
|
+
exports.getSeededCreateTransactionLocalData = getSeededCreateTransactionLocalData;
|
|
78
|
+
/**
|
|
79
|
+
* Merges a partial edit into the working copy. Lines are replaced wholesale when present --
|
|
80
|
+
* a partial line array would silently truncate the form.
|
|
81
|
+
*/
|
|
82
|
+
const mergeCreateTransactionLocalData = (current, update) => ({
|
|
83
|
+
...current,
|
|
84
|
+
...update,
|
|
85
|
+
lines: update.lines ?? current.lines,
|
|
86
|
+
// The type is keyed by the slice, never edited through a merge.
|
|
87
|
+
transactionType: current.transactionType,
|
|
88
|
+
});
|
|
89
|
+
exports.mergeCreateTransactionLocalData = mergeCreateTransactionLocalData;
|
|
90
|
+
const updateCreateTransactionLine = (lines, lineId, update) => lines.map((line) => line.id === lineId ? { ...line, ...update, id: line.id } : line);
|
|
91
|
+
exports.updateCreateTransactionLine = updateCreateTransactionLine;
|
|
92
|
+
/**
|
|
93
|
+
* Recommendation -> RecommendationWithCOT. Chain-of-thought and recommendation feedback both
|
|
94
|
+
* need an existing transaction, so cot/reasoning are empty here by design; the dropdown only
|
|
95
|
+
* needs the entities to build its "Recommended" group.
|
|
96
|
+
*/
|
|
97
|
+
const toRecommendationsWithCOT = (recommendations) => recommendations.map((recommendation) => ({
|
|
98
|
+
account: recommendation.account != null
|
|
99
|
+
? { ...recommendation.account, cot: [], reasoning: '' }
|
|
100
|
+
: undefined,
|
|
101
|
+
class: recommendation.class != null
|
|
102
|
+
? { ...recommendation.class, cot: [], reasoning: '' }
|
|
103
|
+
: undefined,
|
|
104
|
+
vendor: recommendation.vendor != null
|
|
105
|
+
? { ...recommendation.vendor, cot: [], reasoning: '' }
|
|
106
|
+
: undefined,
|
|
107
|
+
}));
|
|
108
|
+
exports.toRecommendationsWithCOT = toRecommendationsWithCOT;
|
|
109
|
+
/**
|
|
110
|
+
* Applies a vendor's recommendations to one line: always refreshes the dropdown's "Recommended"
|
|
111
|
+
* group, but only prefills account/class when the field is still empty. Callers switching
|
|
112
|
+
* vendors clear the previous prefill first, so "empty" includes what the last vendor filled. Anything the user
|
|
113
|
+
* picked wins -- this follows the transaction-categorization helper, which prefills, rather
|
|
114
|
+
* than the detail-page helper, which only suggests.
|
|
115
|
+
*/
|
|
116
|
+
const applyRecommendationsToCreateTransactionLine = (line, recommendations, isAccountingClassesEnabled) => {
|
|
117
|
+
const top = recommendations[0];
|
|
118
|
+
const updated = {
|
|
119
|
+
...line,
|
|
120
|
+
recommendationsWithCOT: (0, exports.toRecommendationsWithCOT)(recommendations),
|
|
121
|
+
};
|
|
122
|
+
if (line.accountQboId == null && top?.account?.qboId != null) {
|
|
123
|
+
updated.accountQboId = top.account.qboId;
|
|
124
|
+
updated.accountName = top.account.accountName;
|
|
125
|
+
updated.isAccountPreFilled = true;
|
|
126
|
+
}
|
|
127
|
+
if (isAccountingClassesEnabled &&
|
|
128
|
+
line.classId == null &&
|
|
129
|
+
top?.class?.classId != null) {
|
|
130
|
+
updated.classId = top.class.classId;
|
|
131
|
+
updated.className = top.class.className;
|
|
132
|
+
updated.isClassPreFilled = true;
|
|
133
|
+
}
|
|
134
|
+
return updated;
|
|
135
|
+
};
|
|
136
|
+
exports.applyRecommendationsToCreateTransactionLine = applyRecommendationsToCreateTransactionLine;
|
|
137
|
+
/**
|
|
138
|
+
* Undoes a prefill when the vendor is cleared. Only the fields the prefill wrote are removed --
|
|
139
|
+
* the per-field flags are what make the user's own choices distinguishable from ours, which is
|
|
140
|
+
* why they are not a single line-level boolean: a hand-picked account alongside a prefilled
|
|
141
|
+
* class is an ordinary state, and clearing must not take the account with it.
|
|
142
|
+
*/
|
|
143
|
+
const clearRecommendationsFromCreateTransactionLine = (line) => {
|
|
144
|
+
const cleared = {
|
|
145
|
+
...line,
|
|
146
|
+
recommendationsWithCOT: undefined,
|
|
147
|
+
};
|
|
148
|
+
if (line.isAccountPreFilled === true) {
|
|
149
|
+
cleared.accountQboId = undefined;
|
|
150
|
+
cleared.accountName = undefined;
|
|
151
|
+
cleared.isAccountPreFilled = undefined;
|
|
152
|
+
}
|
|
153
|
+
if (line.isClassPreFilled === true) {
|
|
154
|
+
cleared.classId = undefined;
|
|
155
|
+
cleared.className = undefined;
|
|
156
|
+
cleared.isClassPreFilled = undefined;
|
|
157
|
+
}
|
|
158
|
+
return cleared;
|
|
159
|
+
};
|
|
160
|
+
exports.clearRecommendationsFromCreateTransactionLine = clearRecommendationsFromCreateTransactionLine;
|