@zeniai/client-epic-state 5.1.81-betaAK4 → 5.1.81-betaAK6
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 +8 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +8 -0
- package/lib/esm/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
- package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +3 -3
- package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +10 -6
- package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +14 -3
- package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +41 -9
- package/lib/index.d.ts +1 -1
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/invoicing/createInvoice/createInvoiceSelector.d.ts +22 -8
- package/lib/view/invoicing/createInvoice/createInvoiceSelector.js +37 -10
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.d.ts +3 -1
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +5 -1
- package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.d.ts +4 -2
- package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewSelector.js +3 -3
- package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +1 -0
- package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +9 -5
- package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.d.ts +10 -1
- package/lib/view/invoicing/issueCreditNote/issueCreditNoteSelector.js +13 -2
- package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.d.ts +2 -1
- package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +40 -8
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const toSnackbarMessageSection: (v: string) => "common" | "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" | "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" | "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" | "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" | "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";
|
|
1
|
+
export declare const toSnackbarMessageSection: (v: string) => "common" | "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" | "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" | "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" | "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" | "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";
|
|
2
2
|
export type SnackbarMessageSections = ReturnType<typeof toSnackbarMessageSection>;
|
|
3
3
|
export declare const toSnackbarMessageSectionTexts: (v: string) => "notification" | "failed" | "success";
|
|
4
4
|
export type SnackbarMessageSectionTexts = ReturnType<typeof toSnackbarMessageSectionTexts>;
|
|
@@ -251,6 +251,14 @@ const ALL_SNACKBAR_MESSAGE_SECTIONS = [
|
|
|
251
251
|
'invoicing_invoice_saved',
|
|
252
252
|
'invoicing_credit_note_saved',
|
|
253
253
|
'invoicing_payment_recorded',
|
|
254
|
+
'invoicing_subscription_activated',
|
|
255
|
+
'invoicing_subscription_cancellation_removed',
|
|
256
|
+
'invoicing_subscription_cancelled',
|
|
257
|
+
'invoicing_subscription_non_renewing',
|
|
258
|
+
'invoicing_subscription_paused',
|
|
259
|
+
'invoicing_subscription_reactivated',
|
|
260
|
+
'invoicing_subscription_resumed',
|
|
261
|
+
'invoicing_subscription_term_end_changed',
|
|
254
262
|
];
|
|
255
263
|
const toSnackbarMessageSection = (v) => (0, stringToUnion_1.stringToUnion)(v, ALL_SNACKBAR_MESSAGE_SECTIONS);
|
|
256
264
|
exports.toSnackbarMessageSection = toSnackbarMessageSection;
|
|
@@ -248,6 +248,14 @@ const ALL_SNACKBAR_MESSAGE_SECTIONS = [
|
|
|
248
248
|
'invoicing_invoice_saved',
|
|
249
249
|
'invoicing_credit_note_saved',
|
|
250
250
|
'invoicing_payment_recorded',
|
|
251
|
+
'invoicing_subscription_activated',
|
|
252
|
+
'invoicing_subscription_cancellation_removed',
|
|
253
|
+
'invoicing_subscription_cancelled',
|
|
254
|
+
'invoicing_subscription_non_renewing',
|
|
255
|
+
'invoicing_subscription_paused',
|
|
256
|
+
'invoicing_subscription_reactivated',
|
|
257
|
+
'invoicing_subscription_resumed',
|
|
258
|
+
'invoicing_subscription_term_end_changed',
|
|
251
259
|
];
|
|
252
260
|
export const toSnackbarMessageSection = (v) => stringToUnion(v, ALL_SNACKBAR_MESSAGE_SECTIONS);
|
|
253
261
|
// Keeping this different from the message type, since we may not have messages in all instances
|
|
@@ -1,25 +1,52 @@
|
|
|
1
|
+
import { getAddressByAddressId } from '../../../entity/address/addressSelector';
|
|
1
2
|
import { getInvoicingCatalogListView, getInvoicingCatalogPrices, } from '../invoicingCatalogListView/invoicingCatalogListViewSelector';
|
|
2
3
|
import { getInvoicingCustomerListView } from '../invoicingCustomerListView/invoicingCustomerListViewSelector';
|
|
3
4
|
import { getInvoicingSettings } from '../settingsView/settingsViewSelector';
|
|
5
|
+
/**
|
|
6
|
+
* Display name for a customer option: company, else the full name, else the
|
|
7
|
+
* email, else the raw id.
|
|
8
|
+
*/
|
|
9
|
+
const customerDisplayName = (customer) => {
|
|
10
|
+
const fullName = [customer.firstName, customer.lastName]
|
|
11
|
+
.filter((part) => part != null && part.trim() !== '')
|
|
12
|
+
.join(' ')
|
|
13
|
+
.trim();
|
|
14
|
+
const company = customer.company?.trim() ?? '';
|
|
15
|
+
const email = customer.email?.trim() ?? '';
|
|
16
|
+
return company !== ''
|
|
17
|
+
? company
|
|
18
|
+
: fullName !== ''
|
|
19
|
+
? fullName
|
|
20
|
+
: email !== ''
|
|
21
|
+
? email
|
|
22
|
+
: customer.id;
|
|
23
|
+
};
|
|
4
24
|
/**
|
|
5
25
|
* Single bundled view for the create-invoice screen — web-ui consumes only this.
|
|
6
26
|
* Carries the form draft (`localData`), the option sources the form needs
|
|
7
|
-
* (
|
|
8
|
-
* state/error, and the id of the invoice last created
|
|
9
|
-
* navigate on success).
|
|
10
|
-
* option shapes.
|
|
27
|
+
* (customer picker rows, catalog plan names, products, settings), the
|
|
28
|
+
* create-invoice fetch state/error, and the id of the invoice last created
|
|
29
|
+
* (`savedInvoiceId`, to navigate on success).
|
|
11
30
|
*/
|
|
12
31
|
export const getCreateInvoiceFormView = (state) => {
|
|
13
32
|
const createInvoiceState = state.invoicingCreateInvoiceState;
|
|
14
33
|
const catalogListView = getInvoicingCatalogListView(state);
|
|
15
|
-
const plans = getInvoicingCatalogPrices(catalogListView.plans);
|
|
16
34
|
return {
|
|
17
|
-
customers: getInvoicingCustomerListView(state).customers
|
|
35
|
+
customers: getInvoicingCustomerListView(state).customers.map((customer) => ({
|
|
36
|
+
billingAddress: customer.billingAddressId != null
|
|
37
|
+
? getAddressByAddressId(state.addressState, customer.billingAddressId)
|
|
38
|
+
: undefined,
|
|
39
|
+
email: customer.email,
|
|
40
|
+
id: customer.id,
|
|
41
|
+
name: customerDisplayName(customer),
|
|
42
|
+
})),
|
|
18
43
|
localData: createInvoiceState.formDraft,
|
|
19
|
-
planNames: plans
|
|
20
|
-
.
|
|
21
|
-
.
|
|
22
|
-
|
|
44
|
+
planNames: catalogListView.plans.flatMap((plan) => (plan.subFamilies ?? [])
|
|
45
|
+
.filter((subFamily) => (subFamily.name ?? '') !== '')
|
|
46
|
+
.map((subFamily) => ({
|
|
47
|
+
planName: plan.name ?? '',
|
|
48
|
+
subFamilyName: subFamily.name ?? '',
|
|
49
|
+
}))),
|
|
23
50
|
products: getInvoicingCatalogPrices(catalogListView.products),
|
|
24
51
|
savedInvoiceId: createInvoiceState.createdInvoiceId,
|
|
25
52
|
settings: getInvoicingSettings(state),
|
package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js
CHANGED
|
@@ -116,17 +116,21 @@ export const catalogDetailEditValuesToSavePayload = (values, itemType = 'plan',
|
|
|
116
116
|
export const createSubFamilyFormToPayload = (itemId, itemType, values) => {
|
|
117
117
|
const name = values.name.trim();
|
|
118
118
|
const priceCode = trimOrUndefined(values.priceCode) ?? toProductCode(name);
|
|
119
|
+
const tiered = isTieredCatalogPricingModel(values.pricingModel);
|
|
119
120
|
const payload = {
|
|
120
121
|
currency_code: 'USD',
|
|
121
122
|
free_quantity: Number(values.freeQuantity) || 0,
|
|
122
123
|
is_taxable: true,
|
|
123
124
|
item_id: itemId,
|
|
124
125
|
name,
|
|
125
|
-
price: values.priceDollars?.amount ?? 0,
|
|
126
|
+
price: tiered ? 0 : (values.priceDollars?.amount ?? 0),
|
|
126
127
|
price_code: priceCode,
|
|
127
128
|
pricing_model: values.pricingModel || 'flat_fee',
|
|
128
129
|
show_description_in_invoices: true,
|
|
129
130
|
};
|
|
131
|
+
if (tiered) {
|
|
132
|
+
payload.tiers = (values.tiers ?? []).map(tierToPayload);
|
|
133
|
+
}
|
|
130
134
|
const description = trimOrUndefined(values.description);
|
|
131
135
|
if (description != null) {
|
|
132
136
|
payload.description = description;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { deriveInvoicingOnboardingStatus, } from './invoicingConfigViewPayload';
|
|
2
2
|
export const getInvoicingConfigView = (state) => {
|
|
3
|
-
const configState = state.invoicingConfigViewState;
|
|
3
|
+
const { acceptTermsFetchState, enableFetchState, ...configState } = state.invoicingConfigViewState;
|
|
4
4
|
return {
|
|
5
5
|
...configState,
|
|
6
|
-
acceptTermsState:
|
|
7
|
-
enableState:
|
|
6
|
+
acceptTermsState: acceptTermsFetchState,
|
|
7
|
+
enableState: enableFetchState,
|
|
8
8
|
status: deriveInvoicingOnboardingStatus(configState.isInvoicingTosAccepted, configState.isInvoicingEnabled),
|
|
9
9
|
};
|
|
10
10
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { from
|
|
1
|
+
import { from } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
@@ -11,11 +11,15 @@ export const startInvoicingQboBackfillEpic = (actions$, _state$, zeniAPI) => act
|
|
|
11
11
|
})
|
|
12
12
|
.pipe(mergeMap((response) => {
|
|
13
13
|
if (isSuccessResponse(response)) {
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
return from([
|
|
15
|
+
startInvoicingQboBackfillSuccess(),
|
|
16
|
+
fetchInvoicingQboSyncHealth(),
|
|
17
|
+
openSnackbar({
|
|
18
|
+
messageSection: 'invoicing_qbo_backfill',
|
|
19
|
+
messageText: 'success',
|
|
20
|
+
type: 'success',
|
|
21
|
+
}),
|
|
22
|
+
]);
|
|
19
23
|
}
|
|
20
24
|
return from([
|
|
21
25
|
startInvoicingQboBackfillFailure(response.status),
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { getInvoiceDetail } from '../invoiceDetail/invoiceDetailSelector';
|
|
2
|
-
import { INVOICING_CREDIT_NOTE_REASON_CODES } from './issueCreditNoteFormConfig';
|
|
2
|
+
import { INVOICING_CREDIT_NOTE_REASON_CODES, initialIssueCreditNoteFormLocalData, } from './issueCreditNoteFormConfig';
|
|
3
|
+
/**
|
|
4
|
+
* The draft is a single global slice, so a draft seeded for a previously opened
|
|
5
|
+
* invoice can still be in state when another invoice's screen mounts. Anything
|
|
6
|
+
* that would render that stale draft next to this invoice is dropped until the
|
|
7
|
+
* screen re-seeds it for `invoiceId`.
|
|
8
|
+
*/
|
|
3
9
|
export const getIssueCreditNoteView = (state, invoiceId) => {
|
|
4
10
|
const invoiceView = getInvoiceDetail(state, invoiceId);
|
|
5
11
|
const { draft, error, fetchState, issuedCreditNoteId } = state.invoicingIssueCreditNoteState;
|
|
12
|
+
const isDraftForInvoice = draft.invoiceId === invoiceId;
|
|
6
13
|
return {
|
|
7
14
|
invoice: invoiceView.invoice,
|
|
8
|
-
isPageReady: invoiceView.fetchState === 'Completed' &&
|
|
15
|
+
isPageReady: invoiceView.fetchState === 'Completed' &&
|
|
16
|
+
isDraftForInvoice &&
|
|
17
|
+
draft.lineItems.length > 0,
|
|
9
18
|
issuedCreditNoteId,
|
|
10
|
-
localData:
|
|
19
|
+
localData: isDraftForInvoice
|
|
20
|
+
? draft
|
|
21
|
+
: initialIssueCreditNoteFormLocalData(invoiceId),
|
|
11
22
|
reasonCodeValues: [...INVOICING_CREDIT_NOTE_REASON_CODES],
|
|
12
23
|
submitState: { error, fetchState },
|
|
13
24
|
error: invoiceView.error,
|
|
@@ -1,13 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { from } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
3
|
import { updateAddresses } from '../../../entity/address/addressReducer';
|
|
4
4
|
import { extractInvoicingSubscriptionAddresses } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload';
|
|
5
5
|
import { updateInvoicingSubscriptions } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer';
|
|
6
|
+
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
6
7
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
7
8
|
import { runInvoicingSubscriptionAction, runInvoicingSubscriptionActionFailure, runInvoicingSubscriptionActionSuccess, } from './subscriptionActionReducer';
|
|
9
|
+
/**
|
|
10
|
+
* Each lifecycle action reports with its own copy. Keyed loosely because the
|
|
11
|
+
* action payload carries a plain `string`; an unmapped kind stays silent.
|
|
12
|
+
*/
|
|
13
|
+
const SNACKBAR_SECTION_BY_ACTION = {
|
|
14
|
+
activate: 'invoicing_subscription_activated',
|
|
15
|
+
cancel: 'invoicing_subscription_cancelled',
|
|
16
|
+
change_term_end: 'invoicing_subscription_term_end_changed',
|
|
17
|
+
pause: 'invoicing_subscription_paused',
|
|
18
|
+
reactivate: 'invoicing_subscription_reactivated',
|
|
19
|
+
remove_scheduled_cancellation: 'invoicing_subscription_cancellation_removed',
|
|
20
|
+
resume: 'invoicing_subscription_resumed',
|
|
21
|
+
set_non_renewing: 'invoicing_subscription_non_renewing',
|
|
22
|
+
};
|
|
8
23
|
export const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(runInvoicingSubscriptionAction.match), mergeMap((action) => {
|
|
9
24
|
const { action: kind, body, id } = action.payload;
|
|
10
25
|
const requestBody = { action: kind, ...(body ?? {}) };
|
|
26
|
+
const snackbarSection = SNACKBAR_SECTION_BY_ACTION[kind];
|
|
27
|
+
const snackbar = (messageText) => snackbarSection == null
|
|
28
|
+
? []
|
|
29
|
+
: [
|
|
30
|
+
openSnackbar({
|
|
31
|
+
messageSection: snackbarSection,
|
|
32
|
+
messageText,
|
|
33
|
+
type: messageText === 'success' ? 'success' : 'error',
|
|
34
|
+
}),
|
|
35
|
+
];
|
|
11
36
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/subscriptions/${encodeURIComponent(id)}/actions`;
|
|
12
37
|
return zeniAPI
|
|
13
38
|
.postAndGetJSON(apiUrl, requestBody)
|
|
@@ -17,15 +42,22 @@ export const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) =
|
|
|
17
42
|
updateInvoicingSubscriptions([response.data], 'merge'),
|
|
18
43
|
updateAddresses(extractInvoicingSubscriptionAddresses([response.data])),
|
|
19
44
|
runInvoicingSubscriptionActionSuccess({ id }),
|
|
45
|
+
...snackbar('success'),
|
|
20
46
|
];
|
|
21
47
|
}
|
|
22
|
-
return
|
|
23
|
-
|
|
48
|
+
return from([
|
|
49
|
+
runInvoicingSubscriptionActionFailure({
|
|
50
|
+
error: response.status,
|
|
51
|
+
id,
|
|
52
|
+
}),
|
|
53
|
+
...snackbar('failed'),
|
|
54
|
+
]);
|
|
55
|
+
}), catchError((error) => from([
|
|
56
|
+
runInvoicingSubscriptionActionFailure({
|
|
57
|
+
error: createZeniAPIStatus('Unexpected Error', 'Subscription action REST API call errored out ' +
|
|
58
|
+
JSON.stringify(error)),
|
|
24
59
|
id,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
JSON.stringify(error)),
|
|
29
|
-
id,
|
|
30
|
-
}))));
|
|
60
|
+
}),
|
|
61
|
+
...snackbar('failed'),
|
|
62
|
+
])));
|
|
31
63
|
}));
|
package/lib/index.d.ts
CHANGED
|
@@ -1071,7 +1071,7 @@ export type { InvoicingAuditFilters } from './view/invoicing/auditView/auditView
|
|
|
1071
1071
|
export { getInvoicingAuditView } from './view/invoicing/auditView/auditViewSelector';
|
|
1072
1072
|
export type { InvoicingAuditView } from './view/invoicing/auditView/auditViewSelector';
|
|
1073
1073
|
export { getCreateInvoiceFormView } from './view/invoicing/createInvoice/createInvoiceSelector';
|
|
1074
|
-
export type { CreateInvoiceFormView } from './view/invoicing/createInvoice/createInvoiceSelector';
|
|
1074
|
+
export type { CreateInvoiceFormView, InvoicingCreateInvoiceCustomerOption, InvoicingPlanNameOption, } from './view/invoicing/createInvoice/createInvoiceSelector';
|
|
1075
1075
|
export { getRecordPaymentFormView, getRecordPaymentInvoiceOptions, getRecordPaymentView, } from './view/invoicing/recordPayment/recordPaymentSelector';
|
|
1076
1076
|
export type { InvoicingRecordPaymentView, RecordPaymentFormView, RecordPaymentInvoiceOption, } from './view/invoicing/recordPayment/recordPaymentSelector';
|
|
1077
1077
|
export { initializeInvoicingCustomerAddress, resetEditInvoicingCustomerDetailView, submitInvoicingCustomerForm, submitInvoicingCustomerFormFailure, submitInvoicingCustomerFormSuccess, updateInvoicingCustomerFormDraft, } from './view/invoicing/editInvoicingCustomerDetailView/editInvoicingCustomerDetailViewReducer';
|
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" | "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" | "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" | "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" | "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" | "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";
|
|
42
|
+
messageSection: "common" | "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" | "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" | "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" | "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" | "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";
|
|
43
43
|
messageText: "notification" | "failed" | "success";
|
|
44
44
|
type: "error" | "success" | "info";
|
|
45
45
|
variables: {
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import { ID } from '../../../commonStateTypes/common';
|
|
2
2
|
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
|
+
import { Address } from '../../../entity/address/addressState';
|
|
3
4
|
import { InvoicingSettingsPayload } from '../../../entity/invoicing/invoicingCommonPayload';
|
|
4
|
-
import { InvoicingCustomer } from '../../../entity/invoicing/invoicingCustomer/invoicingCustomerState';
|
|
5
5
|
import { InvoicingProduct } from '../../../entity/invoicing/product/productState';
|
|
6
6
|
import { RootState } from '../../../reducer';
|
|
7
7
|
import { InvoicingCreateInvoiceFormLocalData } from './createInvoiceState';
|
|
8
|
+
/**
|
|
9
|
+
* One catalog plan price, split into its two naming parts so consumers can
|
|
10
|
+
* compose the label themselves (the plan family name and the sub-family/price
|
|
11
|
+
* name are separate columns in the catalog).
|
|
12
|
+
*/
|
|
13
|
+
export interface InvoicingPlanNameOption {
|
|
14
|
+
planName: string;
|
|
15
|
+
subFamilyName: string;
|
|
16
|
+
}
|
|
17
|
+
/** One customer row of the create-invoice customer picker. */
|
|
18
|
+
export interface InvoicingCreateInvoiceCustomerOption {
|
|
19
|
+
id: ID;
|
|
20
|
+
name: string;
|
|
21
|
+
billingAddress?: Address;
|
|
22
|
+
email?: string;
|
|
23
|
+
}
|
|
8
24
|
export interface CreateInvoiceFormView extends SelectorView {
|
|
9
|
-
customers:
|
|
25
|
+
customers: InvoicingCreateInvoiceCustomerOption[];
|
|
10
26
|
localData: InvoicingCreateInvoiceFormLocalData;
|
|
11
|
-
planNames:
|
|
12
|
-
plans: InvoicingProduct[];
|
|
27
|
+
planNames: InvoicingPlanNameOption[];
|
|
13
28
|
products: InvoicingProduct[];
|
|
14
29
|
savedInvoiceId?: ID;
|
|
15
30
|
settings?: InvoicingSettingsPayload;
|
|
@@ -17,9 +32,8 @@ export interface CreateInvoiceFormView extends SelectorView {
|
|
|
17
32
|
/**
|
|
18
33
|
* Single bundled view for the create-invoice screen — web-ui consumes only this.
|
|
19
34
|
* Carries the form draft (`localData`), the option sources the form needs
|
|
20
|
-
* (
|
|
21
|
-
* state/error, and the id of the invoice last created
|
|
22
|
-
* navigate on success).
|
|
23
|
-
* option shapes.
|
|
35
|
+
* (customer picker rows, catalog plan names, products, settings), the
|
|
36
|
+
* create-invoice fetch state/error, and the id of the invoice last created
|
|
37
|
+
* (`savedInvoiceId`, to navigate on success).
|
|
24
38
|
*/
|
|
25
39
|
export declare const getCreateInvoiceFormView: (state: RootState) => CreateInvoiceFormView;
|
|
@@ -1,28 +1,55 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCreateInvoiceFormView = void 0;
|
|
4
|
+
const addressSelector_1 = require("../../../entity/address/addressSelector");
|
|
4
5
|
const invoicingCatalogListViewSelector_1 = require("../invoicingCatalogListView/invoicingCatalogListViewSelector");
|
|
5
6
|
const invoicingCustomerListViewSelector_1 = require("../invoicingCustomerListView/invoicingCustomerListViewSelector");
|
|
6
7
|
const settingsViewSelector_1 = require("../settingsView/settingsViewSelector");
|
|
8
|
+
/**
|
|
9
|
+
* Display name for a customer option: company, else the full name, else the
|
|
10
|
+
* email, else the raw id.
|
|
11
|
+
*/
|
|
12
|
+
const customerDisplayName = (customer) => {
|
|
13
|
+
const fullName = [customer.firstName, customer.lastName]
|
|
14
|
+
.filter((part) => part != null && part.trim() !== '')
|
|
15
|
+
.join(' ')
|
|
16
|
+
.trim();
|
|
17
|
+
const company = customer.company?.trim() ?? '';
|
|
18
|
+
const email = customer.email?.trim() ?? '';
|
|
19
|
+
return company !== ''
|
|
20
|
+
? company
|
|
21
|
+
: fullName !== ''
|
|
22
|
+
? fullName
|
|
23
|
+
: email !== ''
|
|
24
|
+
? email
|
|
25
|
+
: customer.id;
|
|
26
|
+
};
|
|
7
27
|
/**
|
|
8
28
|
* Single bundled view for the create-invoice screen — web-ui consumes only this.
|
|
9
29
|
* Carries the form draft (`localData`), the option sources the form needs
|
|
10
|
-
* (
|
|
11
|
-
* state/error, and the id of the invoice last created
|
|
12
|
-
* navigate on success).
|
|
13
|
-
* option shapes.
|
|
30
|
+
* (customer picker rows, catalog plan names, products, settings), the
|
|
31
|
+
* create-invoice fetch state/error, and the id of the invoice last created
|
|
32
|
+
* (`savedInvoiceId`, to navigate on success).
|
|
14
33
|
*/
|
|
15
34
|
const getCreateInvoiceFormView = (state) => {
|
|
16
35
|
const createInvoiceState = state.invoicingCreateInvoiceState;
|
|
17
36
|
const catalogListView = (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogListView)(state);
|
|
18
|
-
const plans = (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(catalogListView.plans);
|
|
19
37
|
return {
|
|
20
|
-
customers: (0, invoicingCustomerListViewSelector_1.getInvoicingCustomerListView)(state).customers
|
|
38
|
+
customers: (0, invoicingCustomerListViewSelector_1.getInvoicingCustomerListView)(state).customers.map((customer) => ({
|
|
39
|
+
billingAddress: customer.billingAddressId != null
|
|
40
|
+
? (0, addressSelector_1.getAddressByAddressId)(state.addressState, customer.billingAddressId)
|
|
41
|
+
: undefined,
|
|
42
|
+
email: customer.email,
|
|
43
|
+
id: customer.id,
|
|
44
|
+
name: customerDisplayName(customer),
|
|
45
|
+
})),
|
|
21
46
|
localData: createInvoiceState.formDraft,
|
|
22
|
-
planNames: plans
|
|
23
|
-
.
|
|
24
|
-
.
|
|
25
|
-
|
|
47
|
+
planNames: catalogListView.plans.flatMap((plan) => (plan.subFamilies ?? [])
|
|
48
|
+
.filter((subFamily) => (subFamily.name ?? '') !== '')
|
|
49
|
+
.map((subFamily) => ({
|
|
50
|
+
planName: plan.name ?? '',
|
|
51
|
+
subFamilyName: subFamily.name ?? '',
|
|
52
|
+
}))),
|
|
26
53
|
products: (0, invoicingCatalogListViewSelector_1.getInvoicingCatalogPrices)(catalogListView.products),
|
|
27
54
|
savedInvoiceId: createInvoiceState.createdInvoiceId,
|
|
28
55
|
settings: (0, settingsViewSelector_1.getInvoicingSettings)(state),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Amount } from '../../../commonStateTypes/amount';
|
|
2
2
|
import type { InvoicingPlan } from '../../../entity/invoicing/plan/planState';
|
|
3
3
|
import type { InvoicingProduct } from '../../../entity/invoicing/product/productState';
|
|
4
|
-
import type { InvoicingCatalogItemFormSubFamily } from './editInvoicingCatalogItemDetailViewState';
|
|
4
|
+
import type { InvoicingCatalogItemFormSubFamily, InvoicingCatalogItemFormTier } from './editInvoicingCatalogItemDetailViewState';
|
|
5
5
|
export type CatalogDetailSubFamilyEditValues = InvoicingCatalogItemFormSubFamily;
|
|
6
6
|
export interface CatalogDetailEditValues {
|
|
7
7
|
applicableItems: string[];
|
|
@@ -46,6 +46,8 @@ export interface CreateSubFamilyFormValues {
|
|
|
46
46
|
trialPeriod: string;
|
|
47
47
|
trialPeriodUnit: string;
|
|
48
48
|
priceDollars?: Amount;
|
|
49
|
+
/** Only sent for the tiered pricing models, which price per tier. */
|
|
50
|
+
tiers?: InvoicingCatalogItemFormTier[];
|
|
49
51
|
}
|
|
50
52
|
/** Build POST /catalog/products body for Create sub-family. */
|
|
51
53
|
export declare const createSubFamilyFormToPayload: (itemId: string, itemType: string, values: CreateSubFamilyFormValues) => Record<string, unknown>;
|
|
@@ -121,17 +121,21 @@ exports.catalogDetailEditValuesToSavePayload = catalogDetailEditValuesToSavePayl
|
|
|
121
121
|
const createSubFamilyFormToPayload = (itemId, itemType, values) => {
|
|
122
122
|
const name = values.name.trim();
|
|
123
123
|
const priceCode = trimOrUndefined(values.priceCode) ?? toProductCode(name);
|
|
124
|
+
const tiered = (0, invoicingCatalogItemFormConfig_1.isTieredCatalogPricingModel)(values.pricingModel);
|
|
124
125
|
const payload = {
|
|
125
126
|
currency_code: 'USD',
|
|
126
127
|
free_quantity: Number(values.freeQuantity) || 0,
|
|
127
128
|
is_taxable: true,
|
|
128
129
|
item_id: itemId,
|
|
129
130
|
name,
|
|
130
|
-
price: values.priceDollars?.amount ?? 0,
|
|
131
|
+
price: tiered ? 0 : (values.priceDollars?.amount ?? 0),
|
|
131
132
|
price_code: priceCode,
|
|
132
133
|
pricing_model: values.pricingModel || 'flat_fee',
|
|
133
134
|
show_description_in_invoices: true,
|
|
134
135
|
};
|
|
136
|
+
if (tiered) {
|
|
137
|
+
payload.tiers = (values.tiers ?? []).map(tierToPayload);
|
|
138
|
+
}
|
|
135
139
|
const description = trimOrUndefined(values.description);
|
|
136
140
|
if (description != null) {
|
|
137
141
|
payload.description = description;
|
|
@@ -6,9 +6,11 @@ import { InvoicingConfigViewState } from './invoicingConfigViewState';
|
|
|
6
6
|
* The whole config state plus what only the view layer needs: the derived
|
|
7
7
|
* onboarding `status` and the shorter names consumers use for the two action
|
|
8
8
|
* fetch states. Extending the state means every field the config API grows
|
|
9
|
-
* reaches consumers without touching this selector
|
|
9
|
+
* reaches consumers without touching this selector; the two internal
|
|
10
|
+
* `*FetchState` fields and the state's own validity predicate are omitted so
|
|
11
|
+
* each piece of data has exactly one public name.
|
|
10
12
|
*/
|
|
11
|
-
export interface InvoicingConfigView extends InvoicingConfigViewState {
|
|
13
|
+
export interface InvoicingConfigView extends Omit<InvoicingConfigViewState, 'acceptTermsFetchState' | 'enableFetchState' | 'hasValidState'> {
|
|
12
14
|
acceptTermsState: FetchStateAndError;
|
|
13
15
|
enableState: FetchStateAndError;
|
|
14
16
|
status?: InvoicingOnboardingStatus;
|
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getInvoicingConfigView = void 0;
|
|
4
4
|
const invoicingConfigViewPayload_1 = require("./invoicingConfigViewPayload");
|
|
5
5
|
const getInvoicingConfigView = (state) => {
|
|
6
|
-
const configState = state.invoicingConfigViewState;
|
|
6
|
+
const { acceptTermsFetchState, enableFetchState, ...configState } = state.invoicingConfigViewState;
|
|
7
7
|
return {
|
|
8
8
|
...configState,
|
|
9
|
-
acceptTermsState:
|
|
10
|
-
enableState:
|
|
9
|
+
acceptTermsState: acceptTermsFetchState,
|
|
10
|
+
enableState: enableFetchState,
|
|
11
11
|
status: (0, invoicingConfigViewPayload_1.deriveInvoicingOnboardingStatus)(configState.isInvoicingTosAccepted, configState.isInvoicingEnabled),
|
|
12
12
|
};
|
|
13
13
|
};
|
|
@@ -38,6 +38,7 @@ export interface InvoicingConfigViewState extends FetchedState {
|
|
|
38
38
|
invoicingTosAcceptanceTime?: string;
|
|
39
39
|
invoicingTosAcceptanceUserAgent?: string;
|
|
40
40
|
invoicingTosAcceptanceUserId?: string;
|
|
41
|
+
/** `undefined` means the config has not been loaded yet (cache marker). */
|
|
41
42
|
isInvoicingEnabled?: boolean;
|
|
42
43
|
isInvoicingSettingsSeeded?: boolean;
|
|
43
44
|
isInvoicingTosAccepted?: boolean;
|
|
@@ -14,11 +14,15 @@ const startInvoicingQboBackfillEpic = (actions$, _state$, zeniAPI) => actions$.p
|
|
|
14
14
|
})
|
|
15
15
|
.pipe((0, operators_1.mergeMap)((response) => {
|
|
16
16
|
if ((0, responsePayload_1.isSuccessResponse)(response)) {
|
|
17
|
-
return (0, rxjs_1.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
return (0, rxjs_1.from)([
|
|
18
|
+
(0, invoicingQboViewReducer_1.startInvoicingQboBackfillSuccess)(),
|
|
19
|
+
(0, invoicingQboViewReducer_1.fetchInvoicingQboSyncHealth)(),
|
|
20
|
+
(0, snackbarReducer_1.openSnackbar)({
|
|
21
|
+
messageSection: 'invoicing_qbo_backfill',
|
|
22
|
+
messageText: 'success',
|
|
23
|
+
type: 'success',
|
|
24
|
+
}),
|
|
25
|
+
]);
|
|
22
26
|
}
|
|
23
27
|
return (0, rxjs_1.from)([
|
|
24
28
|
(0, invoicingQboViewReducer_1.startInvoicingQboBackfillFailure)(response.status),
|
|
@@ -10,7 +10,10 @@ import { IssueCreditNoteFormLocalData } from './issueCreditNoteState';
|
|
|
10
10
|
* as `submitState` so a save failure can't be mistaken for a load failure.
|
|
11
11
|
*/
|
|
12
12
|
export interface IssueCreditNoteView extends SelectorView {
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* True once the invoice has loaded and the draft for *this* invoice has line
|
|
15
|
+
* items to credit.
|
|
16
|
+
*/
|
|
14
17
|
isPageReady: boolean;
|
|
15
18
|
localData: IssueCreditNoteFormLocalData;
|
|
16
19
|
reasonCodeValues: string[];
|
|
@@ -18,4 +21,10 @@ export interface IssueCreditNoteView extends SelectorView {
|
|
|
18
21
|
invoice?: InvoicingInvoice;
|
|
19
22
|
issuedCreditNoteId?: ID;
|
|
20
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* The draft is a single global slice, so a draft seeded for a previously opened
|
|
26
|
+
* invoice can still be in state when another invoice's screen mounts. Anything
|
|
27
|
+
* that would render that stale draft next to this invoice is dropped until the
|
|
28
|
+
* screen re-seeds it for `invoiceId`.
|
|
29
|
+
*/
|
|
21
30
|
export declare const getIssueCreditNoteView: (state: RootState, invoiceId: ID) => IssueCreditNoteView;
|
|
@@ -3,14 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getIssueCreditNoteView = void 0;
|
|
4
4
|
const invoiceDetailSelector_1 = require("../invoiceDetail/invoiceDetailSelector");
|
|
5
5
|
const issueCreditNoteFormConfig_1 = require("./issueCreditNoteFormConfig");
|
|
6
|
+
/**
|
|
7
|
+
* The draft is a single global slice, so a draft seeded for a previously opened
|
|
8
|
+
* invoice can still be in state when another invoice's screen mounts. Anything
|
|
9
|
+
* that would render that stale draft next to this invoice is dropped until the
|
|
10
|
+
* screen re-seeds it for `invoiceId`.
|
|
11
|
+
*/
|
|
6
12
|
const getIssueCreditNoteView = (state, invoiceId) => {
|
|
7
13
|
const invoiceView = (0, invoiceDetailSelector_1.getInvoiceDetail)(state, invoiceId);
|
|
8
14
|
const { draft, error, fetchState, issuedCreditNoteId } = state.invoicingIssueCreditNoteState;
|
|
15
|
+
const isDraftForInvoice = draft.invoiceId === invoiceId;
|
|
9
16
|
return {
|
|
10
17
|
invoice: invoiceView.invoice,
|
|
11
|
-
isPageReady: invoiceView.fetchState === 'Completed' &&
|
|
18
|
+
isPageReady: invoiceView.fetchState === 'Completed' &&
|
|
19
|
+
isDraftForInvoice &&
|
|
20
|
+
draft.lineItems.length > 0,
|
|
12
21
|
issuedCreditNoteId,
|
|
13
|
-
localData:
|
|
22
|
+
localData: isDraftForInvoice
|
|
23
|
+
? draft
|
|
24
|
+
: (0, issueCreditNoteFormConfig_1.initialIssueCreditNoteFormLocalData)(invoiceId),
|
|
14
25
|
reasonCodeValues: [...issueCreditNoteFormConfig_1.INVOICING_CREDIT_NOTE_REASON_CODES],
|
|
15
26
|
submitState: { error, fetchState },
|
|
16
27
|
error: invoiceView.error,
|
|
@@ -2,8 +2,9 @@ import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { updateAddresses } from '../../../entity/address/addressReducer';
|
|
4
4
|
import { updateInvoicingSubscriptions } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer';
|
|
5
|
+
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
6
|
import { RootState } from '../../../reducer';
|
|
6
7
|
import { ZeniAPI } from '../../../zeniAPI';
|
|
7
8
|
import { runInvoicingSubscriptionAction, runInvoicingSubscriptionActionFailure, runInvoicingSubscriptionActionSuccess } from './subscriptionActionReducer';
|
|
8
|
-
export type ActionType = ReturnType<typeof runInvoicingSubscriptionAction> | ReturnType<typeof runInvoicingSubscriptionActionSuccess> | ReturnType<typeof runInvoicingSubscriptionActionFailure> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoicingSubscriptions>;
|
|
9
|
+
export type ActionType = ReturnType<typeof runInvoicingSubscriptionAction> | ReturnType<typeof runInvoicingSubscriptionActionSuccess> | ReturnType<typeof runInvoicingSubscriptionActionFailure> | ReturnType<typeof updateAddresses> | ReturnType<typeof updateInvoicingSubscriptions> | ReturnType<typeof openSnackbar>;
|
|
9
10
|
export declare const runInvoicingSubscriptionActionEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -6,11 +6,36 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const addressReducer_1 = require("../../../entity/address/addressReducer");
|
|
7
7
|
const invoicingSubscriptionPayload_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload");
|
|
8
8
|
const invoicingSubscriptionReducer_1 = require("../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer");
|
|
9
|
+
const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
|
|
9
10
|
const responsePayload_1 = require("../../../responsePayload");
|
|
10
11
|
const subscriptionActionReducer_1 = require("./subscriptionActionReducer");
|
|
12
|
+
/**
|
|
13
|
+
* Each lifecycle action reports with its own copy. Keyed loosely because the
|
|
14
|
+
* action payload carries a plain `string`; an unmapped kind stays silent.
|
|
15
|
+
*/
|
|
16
|
+
const SNACKBAR_SECTION_BY_ACTION = {
|
|
17
|
+
activate: 'invoicing_subscription_activated',
|
|
18
|
+
cancel: 'invoicing_subscription_cancelled',
|
|
19
|
+
change_term_end: 'invoicing_subscription_term_end_changed',
|
|
20
|
+
pause: 'invoicing_subscription_paused',
|
|
21
|
+
reactivate: 'invoicing_subscription_reactivated',
|
|
22
|
+
remove_scheduled_cancellation: 'invoicing_subscription_cancellation_removed',
|
|
23
|
+
resume: 'invoicing_subscription_resumed',
|
|
24
|
+
set_non_renewing: 'invoicing_subscription_non_renewing',
|
|
25
|
+
};
|
|
11
26
|
const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(subscriptionActionReducer_1.runInvoicingSubscriptionAction.match), (0, operators_1.mergeMap)((action) => {
|
|
12
27
|
const { action: kind, body, id } = action.payload;
|
|
13
28
|
const requestBody = { action: kind, ...(body ?? {}) };
|
|
29
|
+
const snackbarSection = SNACKBAR_SECTION_BY_ACTION[kind];
|
|
30
|
+
const snackbar = (messageText) => snackbarSection == null
|
|
31
|
+
? []
|
|
32
|
+
: [
|
|
33
|
+
(0, snackbarReducer_1.openSnackbar)({
|
|
34
|
+
messageSection: snackbarSection,
|
|
35
|
+
messageText,
|
|
36
|
+
type: messageText === 'success' ? 'success' : 'error',
|
|
37
|
+
}),
|
|
38
|
+
];
|
|
14
39
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/subscriptions/${encodeURIComponent(id)}/actions`;
|
|
15
40
|
return zeniAPI
|
|
16
41
|
.postAndGetJSON(apiUrl, requestBody)
|
|
@@ -20,16 +45,23 @@ const runInvoicingSubscriptionActionEpic = (actions$, _state$, zeniAPI) => actio
|
|
|
20
45
|
(0, invoicingSubscriptionReducer_1.updateInvoicingSubscriptions)([response.data], 'merge'),
|
|
21
46
|
(0, addressReducer_1.updateAddresses)((0, invoicingSubscriptionPayload_1.extractInvoicingSubscriptionAddresses)([response.data])),
|
|
22
47
|
(0, subscriptionActionReducer_1.runInvoicingSubscriptionActionSuccess)({ id }),
|
|
48
|
+
...snackbar('success'),
|
|
23
49
|
];
|
|
24
50
|
}
|
|
25
|
-
return (0, rxjs_1.
|
|
26
|
-
|
|
51
|
+
return (0, rxjs_1.from)([
|
|
52
|
+
(0, subscriptionActionReducer_1.runInvoicingSubscriptionActionFailure)({
|
|
53
|
+
error: response.status,
|
|
54
|
+
id,
|
|
55
|
+
}),
|
|
56
|
+
...snackbar('failed'),
|
|
57
|
+
]);
|
|
58
|
+
}), (0, operators_1.catchError)((error) => (0, rxjs_1.from)([
|
|
59
|
+
(0, subscriptionActionReducer_1.runInvoicingSubscriptionActionFailure)({
|
|
60
|
+
error: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Subscription action REST API call errored out ' +
|
|
61
|
+
JSON.stringify(error)),
|
|
27
62
|
id,
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
JSON.stringify(error)),
|
|
32
|
-
id,
|
|
33
|
-
}))));
|
|
63
|
+
}),
|
|
64
|
+
...snackbar('failed'),
|
|
65
|
+
])));
|
|
34
66
|
}));
|
|
35
67
|
exports.runInvoicingSubscriptionActionEpic = runInvoicingSubscriptionActionEpic;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.1.81-
|
|
3
|
+
"version": "5.1.81-betaAK6",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|