@zeniai/client-epic-state 5.2.26 → 5.2.27-betaRD0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/lib/entity/aiCfo/aiCfoPayload.d.ts +21 -0
  2. package/lib/entity/aiCfo/aiCfoReducer.js +73 -1
  3. package/lib/entity/aiCfo/aiCfoState.d.ts +24 -0
  4. package/lib/entity/file/fileState.d.ts +3 -3
  5. package/lib/entity/file/fileState.js +2 -0
  6. package/lib/entity/invoicing/creditNote/creditNotePayload.d.ts +0 -1
  7. package/lib/entity/invoicing/creditNote/creditNotePayload.js +0 -1
  8. package/lib/entity/invoicing/creditNote/creditNoteState.d.ts +0 -1
  9. package/lib/entity/invoicing/invoice/invoicePayload.d.ts +0 -1
  10. package/lib/entity/invoicing/invoice/invoicePayload.js +0 -1
  11. package/lib/entity/invoicing/invoice/invoiceState.d.ts +0 -1
  12. package/lib/entity/invoicing/invoicingCommonPayload.d.ts +2 -0
  13. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.d.ts +0 -1
  14. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.js +0 -1
  15. package/lib/entity/invoicing/invoicingCustomer/invoicingCustomerState.d.ts +0 -1
  16. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.d.ts +1 -2
  17. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.js +1 -2
  18. package/lib/entity/invoicing/invoicingSubscription/invoicingSubscriptionState.d.ts +1 -2
  19. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +7 -0
  20. package/lib/epic.d.ts +2 -1
  21. package/lib/epic.js +2 -0
  22. package/lib/esm/entity/aiCfo/aiCfoReducer.js +73 -1
  23. package/lib/esm/entity/file/fileState.js +2 -0
  24. package/lib/esm/entity/invoicing/creditNote/creditNotePayload.js +0 -1
  25. package/lib/esm/entity/invoicing/invoice/invoicePayload.js +0 -1
  26. package/lib/esm/entity/invoicing/invoicingCustomer/invoicingCustomerPayload.js +0 -1
  27. package/lib/esm/entity/invoicing/invoicingSubscription/invoicingSubscriptionPayload.js +1 -2
  28. package/lib/esm/epic.js +2 -0
  29. package/lib/esm/index.js +2 -2
  30. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +5 -0
  31. package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +1 -0
  32. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +22 -0
  33. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +4 -2
  34. package/lib/esm/view/invoicing/dataImportView/dataImportViewSelector.js +2 -0
  35. package/lib/esm/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +2 -0
  36. package/lib/esm/view/invoicing/invoicingOverview/invoicingOverviewPayload.js +0 -1
  37. package/lib/esm/view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewSelector.js +2 -1
  38. package/lib/esm/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.js +1 -0
  39. package/lib/esm/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.js +0 -2
  40. package/lib/esm/view/invoicing/settingsView/invoicingBrandingFormConfig.js +5 -0
  41. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +5 -1
  42. package/lib/esm/view/recommendation/recommendationReducer.js +13 -1
  43. package/lib/esm/view/recommendation/submitRecommendationFeedbackEpic.js +52 -0
  44. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +18 -2
  45. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +0 -1
  46. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +0 -3
  47. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +18 -2
  48. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +0 -1
  49. package/lib/index.d.ts +7 -5
  50. package/lib/index.js +24 -23
  51. package/lib/view/aiCfoView/aiCfoViewReducer.js +5 -0
  52. package/lib/view/aiCfoView/aiCfoViewSelector.js +1 -0
  53. package/lib/view/aiCfoView/aiCfoViewState.d.ts +7 -0
  54. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +22 -0
  55. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +2 -0
  56. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +5 -3
  57. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +2 -5
  58. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +4 -2
  59. package/lib/view/invoicing/dataImportView/dataImportViewSelector.d.ts +2 -0
  60. package/lib/view/invoicing/dataImportView/dataImportViewSelector.js +2 -0
  61. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewPayload.d.ts +1 -0
  62. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.d.ts +1 -1
  63. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewReducer.js +2 -0
  64. package/lib/view/invoicing/invoicingConfigView/invoicingConfigViewState.d.ts +1 -0
  65. package/lib/view/invoicing/invoicingOverview/invoicingOverviewPayload.d.ts +0 -1
  66. package/lib/view/invoicing/invoicingOverview/invoicingOverviewPayload.js +0 -1
  67. package/lib/view/invoicing/invoicingOverview/invoicingOverviewState.d.ts +0 -1
  68. package/lib/view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewSelector.d.ts +3 -1
  69. package/lib/view/invoicing/invoicingSubscriptionDetailView/invoicingSubscriptionDetailViewSelector.js +1 -0
  70. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.d.ts +2 -0
  71. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewSelector.js +1 -0
  72. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +2 -2
  73. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.js +0 -2
  74. package/lib/view/invoicing/issueCreditNote/issueCreditNotePayload.d.ts +0 -1
  75. package/lib/view/invoicing/settingsView/invoicingBrandingFormConfig.d.ts +1 -0
  76. package/lib/view/invoicing/settingsView/invoicingBrandingFormConfig.js +5 -0
  77. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +5 -1
  78. package/lib/view/invoicing/settingsView/settingsViewSelector.js +4 -0
  79. package/lib/view/invoicing/subscriptionAction/subscriptionActionRequestPayload.d.ts +8 -0
  80. package/lib/view/recommendation/recommendationPayload.d.ts +34 -0
  81. package/lib/view/recommendation/recommendationReducer.d.ts +2 -1
  82. package/lib/view/recommendation/recommendationReducer.js +14 -2
  83. package/lib/view/recommendation/submitRecommendationFeedbackEpic.d.ts +7 -0
  84. package/lib/view/recommendation/submitRecommendationFeedbackEpic.js +56 -0
  85. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.d.ts +2 -1
  86. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +18 -2
  87. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +0 -1
  88. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.d.ts +0 -1
  89. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +0 -3
  90. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonState.d.ts +0 -1
  91. package/lib/view/spendManagement/commonHistoryView/commonHistory.d.ts +1 -1
  92. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.d.ts +2 -1
  93. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +18 -2
  94. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +0 -1
  95. package/package.json +1 -1
@@ -110,6 +110,7 @@ function chatHistoryToQA(history) {
110
110
  ? parsedAgentMessage.follow_up_questions
111
111
  : [],
112
112
  suggestedReply: parsedAgentMessage.suggested_reply ?? undefined,
113
+ capabilityPromo: toCapabilityPromo(parsedAgentMessage.capability_promo),
113
114
  assumptions: parsedAgentMessage.assumptions ?? '',
114
115
  insights: parsedAgentMessage.insights ?? '',
115
116
  summarizedTitle: parsedAgentMessage.summarized_title ?? undefined,
@@ -118,6 +119,7 @@ function chatHistoryToQA(history) {
118
119
  artifactTitle: parsedAgentMessage.artifact_title ?? undefined,
119
120
  artifactHostUrl: parsedAgentMessage.artifact_host_url ?? undefined,
120
121
  exports: toAiCfoExports(parsedAgentMessage.exports),
122
+ skillDraft: toSkillDraft(parsedAgentMessage.skill_draft),
121
123
  },
122
124
  createdAt: zeniDate(agentMessage.created_at),
123
125
  };
@@ -368,8 +370,76 @@ const toAiCfoVisualizationData = (data) => {
368
370
  columns,
369
371
  };
370
372
  };
373
+ const AI_CFO_CAPABILITY_PROMO_SURFACES = [
374
+ 'banner',
375
+ 'inline',
376
+ ];
377
+ const toAiCfoCapabilityPromoSurface = (value) => AI_CFO_CAPABILITY_PROMO_SURFACES.find((surface) => surface === value);
378
+ const trimmedOrUndefined = (value) => {
379
+ const trimmed = value?.trim() ?? '';
380
+ return trimmed.length > 0 ? trimmed : undefined;
381
+ };
382
+ const toSkillDraft = (payload) => {
383
+ // Dropped rather than partially built when either required field is missing:
384
+ // a Save control wired to a body the create endpoint would reject is worse
385
+ // than no control, because the failure only surfaces after the click.
386
+ if (payload == null) {
387
+ return undefined;
388
+ }
389
+ // Trimmed to '' FIRST, then chosen by length. Not `??`: a whitespace-only
390
+ // display_name trims to '', which is not nullish, so `??` would keep the
391
+ // empty string and drop a draft that has a perfectly good `name`.
392
+ const rawName = payload.name?.trim() ?? '';
393
+ const rawDisplayName = payload.display_name?.trim() ?? '';
394
+ const name = rawName.length > 0 ? rawName : rawDisplayName;
395
+ const displayName = rawDisplayName.length > 0 ? rawDisplayName : name;
396
+ const instructions = payload.instructions?.trim() ?? '';
397
+ if (name.length === 0 || instructions.length === 0) {
398
+ return undefined;
399
+ }
400
+ const examples = payload.parameter_hints?.examples;
401
+ return {
402
+ // Kept SEPARATE even though the agent currently sends both the same: the
403
+ // create endpoint takes `name` and `display_name` as distinct fields, and
404
+ // collapsing them here would submit the display label as the identifier if
405
+ // they ever diverge.
406
+ name,
407
+ displayName,
408
+ instructions,
409
+ // An empty description is ABSENT, matching the way blank parameter hints
410
+ // are dropped below — `?? undefined` would store ''.
411
+ description: trimmedOrUndefined(payload.description),
412
+ parameterHints: Array.isArray(examples)
413
+ ? examples.filter((hint) => typeof hint === 'string' && hint.trim().length > 0)
414
+ : undefined,
415
+ };
416
+ };
417
+ const toCapabilityPromo = (payload) => {
418
+ // Runtime payloads can miss fields regardless of the wire type — drop the
419
+ // promo on a missing/empty id or copy, and narrow surface to the union.
420
+ if (payload == null || !payload.id || !payload.copy) {
421
+ return undefined;
422
+ }
423
+ const surface = toAiCfoCapabilityPromoSurface(payload.surface);
424
+ if (surface == null) {
425
+ return undefined;
426
+ }
427
+ const cta = toCapabilityPromoCta(payload.cta);
428
+ return {
429
+ copy: payload.copy,
430
+ id: payload.id,
431
+ surface,
432
+ ...(cta != null && { cta }),
433
+ };
434
+ };
435
+ const toCapabilityPromoCta = (payload) => {
436
+ if (payload == null || !payload.label || !payload.prefill) {
437
+ return undefined;
438
+ }
439
+ return { label: payload.label, prefill: payload.prefill };
440
+ };
371
441
  const toResponseBlockType = (answer, userId) => {
372
- const { metadata, state, type, text, visualization, table, follow_up_questions, suggested_reply, assumptions, insights, summarized_title, artifact, artifact_title, artifact_host_url, exports, } = answer;
442
+ const { metadata, state, type, text, visualization, table, follow_up_questions, suggested_reply, assumptions, insights, summarized_title, artifact, artifact_title, artifact_host_url, capability_promo, exports, skill_draft, } = answer;
373
443
  const { chat_session_id, message_id, timestamp, chain_of_thought_action_steps: chainOfThoughtActionSteps = [], } = metadata;
374
444
  return {
375
445
  messageId: message_id,
@@ -384,6 +454,7 @@ const toResponseBlockType = (answer, userId) => {
384
454
  table: table != null ? toAiCfoVisualization(table) : undefined,
385
455
  followUpQuestions: follow_up_questions ?? [],
386
456
  suggestedReply: suggested_reply ?? undefined,
457
+ capabilityPromo: toCapabilityPromo(capability_promo),
387
458
  assumptions: assumptions ?? '',
388
459
  insights: insights ?? '',
389
460
  summarizedTitle: summarized_title ?? undefined,
@@ -392,6 +463,7 @@ const toResponseBlockType = (answer, userId) => {
392
463
  artifactTitle: artifact_title ?? undefined,
393
464
  artifactHostUrl: artifact_host_url ?? undefined,
394
465
  exports: toAiCfoExports(exports),
466
+ skillDraft: toSkillDraft(skill_draft),
395
467
  },
396
468
  createdAt: zeniDate(timestamp),
397
469
  };
@@ -72,6 +72,7 @@ const ALLOWED_DOCUMENT_TYPES = [
72
72
  'bill_pay',
73
73
  'certificate_of_incorporation',
74
74
  'check',
75
+ 'company_logo',
75
76
  'contract',
76
77
  'driving_license',
77
78
  'employer_identification_number_confirmation',
@@ -95,6 +96,7 @@ const ALLOWED_PURPOSE_IDS = [
95
96
  'business_verification_others',
96
97
  'bill_pay',
97
98
  'international_wire_business_verification',
99
+ 'company_logo',
98
100
  'others',
99
101
  ];
100
102
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -9,7 +9,6 @@ export const mapInvoicingCreditNoteLineItemPayloadToState = (payload, currencyCo
9
9
  unitAmount: toAmount(payload.unit_amount, currencyCode, currencySymbol),
10
10
  entityType: payload.entity_type,
11
11
  id: payload.id,
12
- productCode: payload.product_code,
13
12
  });
14
13
  export const mapInvoicingCreditNoteAllocationPayloadToState = (payload, currencyCode, currencySymbol) => ({
15
14
  allocatedAmount: toAmount(payload.allocated_amount, currencyCode, currencySymbol),
@@ -19,7 +19,6 @@ const mapLineItem = (payload, currencyCode, currencySymbol) => ({
19
19
  itemLevelDiscountAmount: payload.item_level_discount_amount != null
20
20
  ? toAmount(payload.item_level_discount_amount, currencyCode, currencySymbol)
21
21
  : undefined,
22
- productCode: payload.product_code,
23
22
  subscriptionID: payload.subscription_id,
24
23
  taxAmount: payload.tax_amount != null
25
24
  ? toAmount(payload.tax_amount, currencyCode, currencySymbol)
@@ -72,7 +72,6 @@ export const mapInvoicingCustomerPayloadToState = (payload) => {
72
72
  phone: payload.phone,
73
73
  plan: payload.plan,
74
74
  planName: payload.plan_name,
75
- productCode: payload.product_code,
76
75
  preferredCurrencyCode: payload.preferred_currency_code,
77
76
  promotionalCredits: payload.promotional_credits != null
78
77
  ? toAmount(payload.promotional_credits, currencyCode, currencySymbol)
@@ -12,7 +12,6 @@ export const mapInvoicingSubscriptionItemPayloadToState = (payload, currencyCode
12
12
  itemPriceCode: payload.item_price_code,
13
13
  itemPriceID: payload.item_price_id,
14
14
  itemType: payload.item_type,
15
- productCode: payload.product_code,
16
15
  quantity: payload.quantity,
17
16
  unitPrice: payload.unit_price != null
18
17
  ? toAmount(payload.unit_price, currencyCode, currencySymbol)
@@ -58,6 +57,7 @@ export const mapInvoicingSubscriptionPayloadToState = (payload) => {
58
57
  billingPeriod: payload.billing_period,
59
58
  billingPeriodUnit: payload.billing_period_unit,
60
59
  cancelReason: payload.cancel_reason,
60
+ cancelReasonCode: payload.cancel_reason_code,
61
61
  cancelledAt: payload.cancelled_at != null ? date(payload.cancelled_at) : undefined,
62
62
  catalogItemID: payload.catalog_item_id,
63
63
  contractTerm: payload.contract_term != null
@@ -88,7 +88,6 @@ export const mapInvoicingSubscriptionPayloadToState = (payload) => {
88
88
  : undefined,
89
89
  planID: payload.plan_id,
90
90
  planName: payload.plan_name,
91
- productCode: payload.product_code,
92
91
  poNumber: payload.po_number,
93
92
  remainingBillingCycles: payload.remaining_billing_cycles,
94
93
  resumeDate: payload.resume_date != null ? date(payload.resume_date) : undefined,
package/lib/esm/epic.js CHANGED
@@ -400,6 +400,7 @@ import { fetchEntityRecommendationsByTransactionIdEpic, } from './view/recommend
400
400
  import { fetchEntityRecommendationsForLineUpdateEpic, } from './view/recommendation/fetchEntityRecommendationsForLineUpdateEpic';
401
401
  import { fetchRecommendationByEntityIdEpic, } from './view/recommendation/fetchRecommendationByEntityIdEpic';
402
402
  import { fetchRecommendationByEntityNameEpic, } from './view/recommendation/fetchRecommendationByEntityNameEpic';
403
+ import { submitRecommendationFeedbackEpic, } from './view/recommendation/submitRecommendationFeedbackEpic';
403
404
  import { fetchReferralsEpic, } from './view/referralView/epics/fetchReferralsEpic';
404
405
  import { fetchRewardsPlanEpic, } from './view/referralView/epics/fetchRewardsPlanEpic';
405
406
  import { resendReferralInviteEpic, } from './view/referralView/epics/resendReferralInviteEpic';
@@ -1382,6 +1383,7 @@ const ALL_EPICS = [
1382
1383
  submitInvoicingBrandingFormEpic,
1383
1384
  submitInvoicingQboSettingsEpic,
1384
1385
  submitQuestionEpic,
1386
+ submitRecommendationFeedbackEpic,
1385
1387
  switchExpenseAutomationJESchedulesTabEpic,
1386
1388
  syncInvoicingSubscriptionCouponsEpic,
1387
1389
  syncTabsAfterAutomatchEpic,
package/lib/esm/index.js CHANGED
@@ -266,7 +266,7 @@ import { fetchProfitAndLossForTimeframeProjectView, fetchProfitAndLossProjectVie
266
266
  import { getProfitAndLossProjectView } from './view/profitAndLossProjectView/profitAndLossProjectViewSelector';
267
267
  import { fetchProjectList } from './view/projectList/projectListReducer';
268
268
  import { getProjectList, } from './view/projectList/projectListSelector';
269
- import { fetchEntityRecommendationsByTransactionId, fetchEntityRecommendationsForLineUpdate, fetchRecommendationByEntityId, fetchRecommendationByEntityName, } from './view/recommendation/recommendationReducer';
269
+ import { fetchEntityRecommendationsByTransactionId, fetchEntityRecommendationsForLineUpdate, fetchRecommendationByEntityId, fetchRecommendationByEntityName, submitRecommendationFeedback, } from './view/recommendation/recommendationReducer';
270
270
  import { DEFAULT_REFERRER_AMOUNT, clearReferrals, fetchReferrals, fetchRewardsPlan, resendReferralInvite, saveReferralFormDataInLocalStore, sendReferralInvite, updateReferViewed, updateReferralListSortUiState, } from './view/referralView/referralReducer';
271
271
  import { getInviteFormView, getReferralListView, getRewardsPlanCard, } from './view/referralView/referralSelector';
272
272
  import { AmountStatusTypes, StatusTypes, toReferralListViewSortKeyType, } from './view/referralView/referralState';
@@ -632,7 +632,7 @@ export { getSpendManagementEffectiveListPeriod, getSelectedCompanyOfficer, showB
632
632
  export { canSendMonthEndEmailReport, shouldEnableCalendarPickerForLastReportSent, };
633
633
  export { getInternationalSubConfigCodeKey, BILL_NEW_PAYMENT_METHODS, NEW_INTERNATIONAL_METHOD_SUBTEXT, SWIFT_OUR_INTERNATIONAL_METHOD_SUBTEXT, LOCAL_CURRENCY_INTERNATIONAL_METHOD_SUBTEXT, };
634
634
  export { getVendorList, updateSortUiState, updatePageToken, updateYTDSelectionUIState, isColumnYTDSpend, isVendorsTabVisible, toVendorReportIDType, getVendorFiling1099List, fetchVendorsFiling1099Download, };
635
- export { fetchEntityRecommendationsByTransactionId, fetchEntityRecommendationsForLineUpdate, fetchRecommendationByEntityId, fetchRecommendationByEntityName, };
635
+ export { fetchEntityRecommendationsByTransactionId, fetchEntityRecommendationsForLineUpdate, fetchRecommendationByEntityId, fetchRecommendationByEntityName, submitRecommendationFeedback, };
636
636
  export { fetchOwnerList };
637
637
  export { getZeniAccountsConfigDetail, getZeniAccountList, fetchZeniAccountList, fetchAccountList, createCheckingAccount, fetchPaymentAccountList, unlinkPaymentAccount, getDepositAccountDetail, getAllDepositAccounts, getDepositAccountDetailForPDF, fetchDepositAccount, fetchZeniAccountsConfig, updateTransferMoneyLocalData, updateTransferToLocalData, updateDepositToLocalData, transferMoney, getTransferDetail, clearTransferDetail, clearReviewTransferDetail, fetchReviewTransferDetail, fetchDepositAccountDetail, depositCheck, updateCheckDepositLocalData, clearCheckDeposit, getCheckDepositDetail, updateDepositAccount, fetchDepositAccountHistorySuccess, fetchDepositAccountHistoryFailure, fetchZeniAccStatementPage, getZeniAccStatements, };
638
638
  export { fetchDepositAccountTransactionList, getDepositAccountTransactionList, };
@@ -58,6 +58,7 @@ export const initialAiCfoViewState = {
58
58
  fetchState: 'Not-Started',
59
59
  error: undefined,
60
60
  savedMacroId: undefined,
61
+ kind: undefined,
61
62
  },
62
63
  skillVersionBody: {
63
64
  fetchState: 'Not-Started',
@@ -777,6 +778,7 @@ const aiCfoView = createSlice({
777
778
  fetchState: 'In-Progress',
778
779
  error: undefined,
779
780
  savedMacroId: undefined,
781
+ kind: 'save',
780
782
  };
781
783
  },
782
784
  prepare(payload) {
@@ -828,6 +830,7 @@ const aiCfoView = createSlice({
828
830
  fetchState: 'In-Progress',
829
831
  error: undefined,
830
832
  savedMacroId: undefined,
833
+ kind: 'visibility',
831
834
  };
832
835
  },
833
836
  prepare(payload) {
@@ -863,6 +866,7 @@ const aiCfoView = createSlice({
863
866
  fetchState: 'In-Progress',
864
867
  error: undefined,
865
868
  savedMacroId: undefined,
869
+ kind: 'delete',
866
870
  };
867
871
  },
868
872
  prepare(payload) {
@@ -891,6 +895,7 @@ const aiCfoView = createSlice({
891
895
  fetchState: 'Not-Started',
892
896
  error: undefined,
893
897
  savedMacroId: undefined,
898
+ kind: undefined,
894
899
  };
895
900
  },
896
901
  openSkillsBrowser(draft) {
@@ -62,6 +62,7 @@ const EMPTY_SKILL_MUTATION_STATE = {
62
62
  fetchState: 'Not-Started',
63
63
  error: undefined,
64
64
  savedMacroId: undefined,
65
+ kind: undefined,
65
66
  };
66
67
  export function getSkills(state) {
67
68
  return state.aiCfoViewState?.skills ?? EMPTY_SKILLS_STATE;
@@ -73,17 +73,39 @@ export const promoteOneTimeAccrualEpic = (actions$, state$, zeniAPI) => actions$
73
73
  const debitClassId = edits?.jeDebitAccountingClassId ?? accrual?.jeDebitAccountingClassId;
74
74
  const debitClassName = edits?.jeDebitAccountingClassName ??
75
75
  accrual?.jeDebitAccountingClassName;
76
+ // The accrual document stores names alongside ids, so every id below travels with its name.
77
+ // Sending an id on its own leaves the stored row -- and the JE posted from it -- naming the
78
+ // account the user just moved away from. Create has always sent the full set; promote did
79
+ // not, which is the difference the two paths were showing.
80
+ const debitAccountName = edits?.jeDebitAccountName ?? accrual?.jeDebitAccountName;
81
+ const creditAccountName = edits?.jeCreditAccountName ?? accrual?.jeCreditAccountName;
82
+ // Credit-side class is never edited on this form -- the liability side is the Balance Sheet
83
+ // class the draft was born with -- so it is echoed straight back from the draft.
84
+ const creditClassId = accrual?.jeCreditAccountingClassId;
85
+ const creditClassName = accrual?.jeCreditAccountingClassName;
76
86
  const payload = {
77
87
  amount,
78
88
  memo: edits?.memo ?? accrual?.memo ?? '',
79
89
  je_debit_account_id: debitAccountId,
80
90
  je_credit_account_id: creditAccountId,
91
+ ...(debitAccountName != null
92
+ ? { je_debit_account_name: debitAccountName }
93
+ : {}),
94
+ ...(creditAccountName != null
95
+ ? { je_credit_account_name: creditAccountName }
96
+ : {}),
81
97
  ...(debitClassId != null
82
98
  ? { je_debit_accounting_class_id: debitClassId }
83
99
  : {}),
84
100
  ...(debitClassName != null
85
101
  ? { je_debit_accounting_class_name: debitClassName }
86
102
  : {}),
103
+ ...(creditClassId != null
104
+ ? { je_credit_accounting_class_id: creditClassId }
105
+ : {}),
106
+ ...(creditClassName != null
107
+ ? { je_credit_accounting_class_name: creditClassName }
108
+ : {}),
87
109
  // Mirrors the create payload: reverse_next_month alone decides the policy, and the date is
88
110
  // only meaningful when it is true -- agent-je derives the reversal from the bill otherwise.
89
111
  reverse_next_month: reverseNextMonth,
@@ -12,8 +12,8 @@ import { getClassList, getNestedClassListHierarchy, } from '../../classList/clas
12
12
  import { getAccountsTypesForScheduleDetails } from '../../scheduleView/scheduleDetailView/scheduleDetailLocalDataHelper';
13
13
  import { filterNestedAccountHierarchyById } from '../../scheduleView/scheduleDetailView/scheduleDetailSelector';
14
14
  import { getAccountLabelForScheduleType, getAccountsTypesForScheduleList, } from '../../scheduleView/scheduleListView/scheduleListHelper';
15
- import { getAllSteps } from './getAllStepsHelper';
16
15
  import { ALL_JE_PAGE_TABS, getJESchedulePeriodTabKey, } from '../types/jeSchedulesViewState';
16
+ import { getAllSteps } from './getAllStepsHelper';
17
17
  import { getJEAccountSettingsView } from './jeAccountSettingsViewSelector';
18
18
  import { getNewScheduleView } from './jeNewScheduleViewSelector';
19
19
  // Matches the AI-automation user addresses webc's schedule list row already
@@ -330,7 +330,9 @@ export function getExpenseAutomationJESchedulesView(state) {
330
330
  */
331
331
  const sumToAmount = (schedules) => {
332
332
  const first = schedules[0];
333
- const currency = first != null ? getScheduleAmountObject(first) : allScheduleAmountFallback;
333
+ const currency = first != null
334
+ ? getScheduleAmountObject(first)
335
+ : allScheduleAmountFallback;
334
336
  return {
335
337
  ...currency,
336
338
  amount: sumAmount(schedules),
@@ -1,3 +1,4 @@
1
+ import { invoicingFieldHelpForGroup } from '../invoicingConfigView/invoicingConfigViewSelector';
1
2
  /**
2
3
  * Single bundled view for the invoicing data-import surfaces — consumers read
3
4
  * only this. Carries the migration `sessions` list + `sessionsFetch`, the
@@ -7,6 +8,7 @@
7
8
  export const getInvoicingDataImportView = (state) => {
8
9
  const dataImportState = state.invoicingDataImportViewState;
9
10
  return {
11
+ fieldHelp: invoicingFieldHelpForGroup(state, 'data_import'),
10
12
  activeMigrationSessionId: dataImportState.activeDetailId,
11
13
  sessionDetail: dataImportState.sessionDetail,
12
14
  sessionDetailFetch: dataImportState.sessionDetailFetch,
@@ -34,6 +34,7 @@ export const initialState = {
34
34
  discountStatusOptions: [],
35
35
  dunningCaseStatusOptions: [],
36
36
  invoiceStatusOptions: [],
37
+ subscriptionCancelReasonCodeOptions: [],
37
38
  subscriptionStatusOptions: [],
38
39
  transactionStatusOptions: [],
39
40
  transactionTypeOptions: [],
@@ -103,6 +104,7 @@ export function mapInvoicingConfigPayloadToState(payload) {
103
104
  discountStatusOptions: (payload.discount_status_options ?? []).map(toInvoicingNamedOption),
104
105
  dunningCaseStatusOptions: (payload.dunning_case_status_options ?? []).map(toInvoicingNamedOption),
105
106
  invoiceStatusOptions: (payload.invoice_status_options ?? []).map(toInvoicingNamedOption),
107
+ subscriptionCancelReasonCodeOptions: (payload.subscription_cancel_reason_code_options ?? []).map(toInvoicingNamedOption),
106
108
  subscriptionStatusOptions: (payload.subscription_status_options ?? []).map(toInvoicingNamedOption),
107
109
  transactionStatusOptions: (payload.transaction_status_options ?? []).map(toInvoicingNamedOption),
108
110
  transactionTypeOptions: (payload.transaction_type_options ?? []).map(toInvoicingNamedOption),
@@ -37,7 +37,6 @@ export const mapInvoicingPlanRevenuePointPayloadToState = (payload) => ({
37
37
  mrr: toAmount(payload.mrr, 'USD', '$'),
38
38
  pct: payload.pct,
39
39
  planID: payload.plan,
40
- productCode: payload.product_code,
41
40
  });
42
41
  export const mapInvoicingDashboardSummaryPayloadToState = (payload) => ({
43
42
  customerMovement: {
@@ -1,11 +1,12 @@
1
1
  import { getInvoicingSubscriptionById as getInvoicingSubscriptionByIdFromState } from '../../../entity/invoicing/invoicingSubscription/invoicingSubscriptionSelector';
2
- import { invoicingFieldHelpForGroup } from '../invoicingConfigView/invoicingConfigViewSelector';
2
+ import { getInvoicingConfigView, invoicingFieldHelpForGroup, } from '../invoicingConfigView/invoicingConfigViewSelector';
3
3
  import { getInvoicingSubscriptionActionState } from '../subscriptionAction/subscriptionActionSelector';
4
4
  export const getInvoicingSubscriptionById = (state, id) => getInvoicingSubscriptionByIdFromState(state.invoicingSubscriptionState, id);
5
5
  export const getInvoicingSubscriptionDetail = (state, invoicingSubscriptionID) => {
6
6
  const { error, fetchState } = state.invoicingSubscriptionDetailViewState;
7
7
  return {
8
8
  fieldHelp: invoicingFieldHelpForGroup(state, 'subscription'),
9
+ cancelReasonCodeOptions: getInvoicingConfigView(state).subscriptionCancelReasonCodeOptions,
9
10
  actionState: getInvoicingSubscriptionActionState(invoicingSubscriptionID)(state),
10
11
  subscription: getInvoicingSubscriptionById(state, invoicingSubscriptionID),
11
12
  fetchState,
@@ -28,6 +28,7 @@ export const getInvoicingSubscriptionListView = createSelector((state) => state.
28
28
  count: listViewState.counts,
29
29
  countsFetchState: listViewState.countsFetchState,
30
30
  subscriptionCommercialEditAllowedFromStatuses: configState.subscriptionCommercialEditAllowedFromStatuses,
31
+ cancelReasonCodeOptions: configState.subscriptionCancelReasonCodeOptions,
31
32
  subscriptionLifecycleActionOptions: configState.subscriptionLifecycleActionOptions,
32
33
  subscriptionMetadataEditAllowedFromStatuses: configState.subscriptionMetadataEditAllowedFromStatuses,
33
34
  statusOptions,
@@ -3,7 +3,6 @@ export const ALL_INVOICING_SUBSCRIPTION_SORT_KEYS = [
3
3
  'subscription',
4
4
  'customer',
5
5
  'plan',
6
- 'product_code',
7
6
  'term_end',
8
7
  'next_billing',
9
8
  'auto_collect',
@@ -15,7 +14,6 @@ export const INVOICING_SUBSCRIPTION_COLUMNS = [
15
14
  { key: 'subscription', sortable: true },
16
15
  { key: 'customer', sortable: false },
17
16
  { key: 'plan', sortable: true },
18
- { key: 'product_code', sortable: true },
19
17
  { key: 'term_end', sortable: true },
20
18
  { key: 'next_billing', sortable: true },
21
19
  { key: 'auto_collect', sortable: true },
@@ -7,6 +7,7 @@ export const initialInvoicingBrandingFormLocalData = {
7
7
  dateFormat: '',
8
8
  defaultMemo: '',
9
9
  email: '',
10
+ invoiceFooterText: '',
10
11
  invoicePrefix: '',
11
12
  logoFileId: '',
12
13
  phone: '',
@@ -19,6 +20,7 @@ export const entityToInvoicingBrandingFormLocalData = (settings) => ({
19
20
  dateFormat: settings?.date_format ?? '',
20
21
  defaultMemo: settings?.default_memo ?? '',
21
22
  email: settings?.email ?? '',
23
+ invoiceFooterText: settings?.invoice_footer_text ?? '',
22
24
  invoicePrefix: settings?.invoice_prefix ?? '',
23
25
  logoFileId: settings?.logo_file_id ?? '',
24
26
  phone: settings?.phone ?? '',
@@ -39,6 +41,9 @@ export const brandingLocalDataToSettingsPayload = (localData, address) => ({
39
41
  date_format: trimOrUndefined(localData.dateFormat),
40
42
  default_memo: trimOrUndefined(localData.defaultMemo),
41
43
  email: trimOrUndefined(localData.email),
44
+ // Sent even when blank: "" is how the API is told to hide the footer line,
45
+ // so this one must not collapse to `undefined` like the fields above.
46
+ invoice_footer_text: localData.invoiceFooterText.trim(),
42
47
  invoice_prefix: trimOrUndefined(localData.invoicePrefix),
43
48
  logo_file_id: localData.logoFileId,
44
49
  phone: trimOrUndefined(localData.phone),
@@ -1,6 +1,6 @@
1
1
  import { getInvoicingQboAccountMappingId, } from '../../../entity/invoicing/invoicingCommonPayload';
2
2
  import { getFormattedAddress } from '../../addressView/addressViewSelector';
3
- import { getInvoicingConfigView } from '../invoicingConfigView/invoicingConfigViewSelector';
3
+ import { getInvoicingConfigView, invoicingFieldHelpForGroup, } from '../invoicingConfigView/invoicingConfigViewSelector';
4
4
  import { getInvoicingQboView, isInvoicingAccountingPickerDataLoading, } from '../invoicingQboView/invoicingQboViewSelector';
5
5
  import { INVOICING_BUSINESS_ADDRESS_TYPE, entityToInvoicingBrandingFormLocalData, } from './invoicingBrandingFormConfig';
6
6
  import { initialInvoicingQboSettingsLocalData, } from './invoicingQboSettingsFormConfig';
@@ -26,6 +26,7 @@ export const getInvoicingSettingsFetchState = (state) => ({
26
26
  export const getInvoicingSettingsView = (state) => {
27
27
  const { error, fetchState, saveFetchState, settings, stripeFetchState } = state.invoicingSettingsViewState;
28
28
  return {
29
+ fieldHelp: invoicingFieldHelpForGroup(state, 'settings'),
29
30
  error,
30
31
  fetchState,
31
32
  saveState: saveFetchState,
@@ -78,6 +79,7 @@ export const getInvoicingSettingsHubView = (state) => {
78
79
  const { dunningScheduleActionOptions, enableState, error: configError, fetchState: configFetchState, qboAccountMappingKindOptions, qboCustomerMatchingOptions, qboSyncStatusOptions, status, } = getInvoicingConfigView(state);
79
80
  const { canEnable, isQboConfigured, isStripeConnected } = deriveInvoicingEnablePrerequisites(state.invoicingSettingsViewState.settings, state.invoicingQboViewState.connection?.connected === true, qboAccountMappingKindOptions);
80
81
  return {
82
+ fieldHelp: invoicingFieldHelpForGroup(state, 'settings'),
81
83
  // Keeps the onboarding step in the gate: a tenant that has not accepted the
82
84
  // terms cannot enable invoicing, whatever the integrations say.
83
85
  canEnableInvoicing: status === 'settings' && canEnable,
@@ -108,6 +110,7 @@ export const getInvoicingQboSettingsFormView = (state) => {
108
110
  const { fetchState: configFetchState, qboAccountMappingKindOptions, qboCustomerMatchingOptions, qboSyncStatusOptions, } = getInvoicingConfigView(state);
109
111
  const qboView = getInvoicingQboView(state);
110
112
  return {
113
+ fieldHelp: invoicingFieldHelpForGroup(state, 'settings'),
111
114
  accountMappingKindOptions: qboAccountMappingKindOptions,
112
115
  accounts: qboView.accounts,
113
116
  backfillState: qboView.backfillState,
@@ -147,6 +150,7 @@ export const getInvoicingBrandingFormView = (state) => {
147
150
  ? getFormattedAddress(newAddress.addressToCreate)
148
151
  : undefined;
149
152
  return {
153
+ fieldHelp: invoicingFieldHelpForGroup(state, 'settings'),
150
154
  addressLabel,
151
155
  dateFormatOptions: getInvoicingConfigView(state).dateFormatOptions,
152
156
  localData: brandingDraft ?? entityToInvoicingBrandingFormLocalData(settings),
@@ -131,6 +131,18 @@ const recommendation = createSlice({
131
131
  };
132
132
  },
133
133
  },
134
+ // Fire-and-forget human feedback on a recommendation (accept, ranked
135
+ // override or outside override). Handled by submitRecommendationFeedbackEpic
136
+ // which POSTs to the accounting recommendation-feedback endpoint. No state
137
+ // mutation: the categorization UX must not depend on the feedback round-trip.
138
+ submitRecommendationFeedback: {
139
+ reducer() {
140
+ // Fire-and-forget: no state mutation; the epic performs the POST.
141
+ },
142
+ prepare(args) {
143
+ return { payload: args };
144
+ },
145
+ },
134
146
  },
135
147
  extraReducers: (builder) => {
136
148
  builder.addCase(clearAll, (draft) => {
@@ -138,7 +150,7 @@ const recommendation = createSlice({
138
150
  });
139
151
  },
140
152
  });
141
- export const { fetchEntityRecommendationsByTransactionId, fetchEntityRecommendationsForLineUpdate, fetchRecommendationByEntityName, fetchRecommendationByEntityId, updateRecommendationForEntity, updateRecommendationForEntityFailure, indicateReadyToInitializeRecommendation, } = recommendation.actions;
153
+ export const { fetchEntityRecommendationsByTransactionId, fetchEntityRecommendationsForLineUpdate, fetchRecommendationByEntityName, fetchRecommendationByEntityId, updateRecommendationForEntity, updateRecommendationForEntityFailure, indicateReadyToInitializeRecommendation, submitRecommendationFeedback, } = recommendation.actions;
142
154
  export default recommendation.reducer;
143
155
  const doUpdateRecommendationForEntity = (draft, entityId, entityType, payload) => {
144
156
  const key = getEntityRecommendationKey(entityType, entityId);
@@ -0,0 +1,52 @@
1
+ import { EMPTY } from 'rxjs';
2
+ import { catchError, filter, mergeMap } from 'rxjs/operators';
3
+ import { isSuccessStatus } from '../../responsePayload';
4
+ import { submitRecommendationFeedback } from './recommendationReducer';
5
+ const toRequestBody = (payload) => ({
6
+ line_id: payload.lineId ?? null,
7
+ dimension: payload.dimension,
8
+ recommendation_set_id: payload.recommendationSetId ?? null,
9
+ top_pick_source: payload.topPickSource ?? null,
10
+ shown_recommendations: (payload.shownRecommendations ?? []).map((recommendation) => ({
11
+ source: recommendation.source,
12
+ rank: recommendation.rank,
13
+ value: {
14
+ name: recommendation.value.name,
15
+ id: recommendation.value.id ?? null,
16
+ integration_id: recommendation.value.integrationId ?? null,
17
+ },
18
+ confidence: recommendation.confidence ?? null,
19
+ reasoning: recommendation.reasoning ?? null,
20
+ cot: recommendation.cot ?? [],
21
+ })),
22
+ selected: {
23
+ name: payload.selected.name,
24
+ id: payload.selected.id ?? null,
25
+ integration_id: payload.selected.integrationId ?? null,
26
+ is_new_entity: payload.selected.isNewEntity ?? false,
27
+ },
28
+ matched_source: payload.matchedSource ?? null,
29
+ matched_rank: payload.matchedRank ?? null,
30
+ outcome: payload.outcome,
31
+ reason_text: payload.reasonText ?? null,
32
+ skipped: payload.skipped ?? false,
33
+ retracts_feedback_id: payload.retractsFeedbackId ?? null,
34
+ features: payload.features ?? null,
35
+ });
36
+ // Fire-and-forget: the epic never re-emits an action. Feedback delivery is a
37
+ // side-effect that must not disrupt the categorization UX, so both the
38
+ // success and error paths complete silently (errors are logged for debugging).
39
+ export const submitRecommendationFeedbackEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(submitRecommendationFeedback.match), mergeMap((action) => {
40
+ const { transactionId } = action.payload;
41
+ return zeniAPI
42
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/transactions/${transactionId}/recommendation-feedback`, toRequestBody(action.payload))
43
+ .pipe(mergeMap((response) => {
44
+ if (!isSuccessStatus(response)) {
45
+ console.error('submitRecommendationFeedbackEpic: recommendation feedback was not recorded', response.status);
46
+ }
47
+ return EMPTY;
48
+ }), catchError((error) => {
49
+ console.error('submitRecommendationFeedbackEpic: failed to submit recommendation feedback', error);
50
+ return EMPTY;
51
+ }));
52
+ }));
@@ -2,13 +2,20 @@ import { from, of } from 'rxjs';
2
2
  import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
3
  import { updateApprovalRules } from '../../../../../entity/approvalRule/approvalRuleReducer';
4
4
  import { getApprovalRulesByIds } from '../../../../../entity/approvalRule/approvalRuleSelector';
5
+ import { getIsAccountingClassesEnabled } from '../../../../../entity/tenant/tenantSelector';
5
6
  import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
7
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
8
+ import { fetchClassList } from '../../../../classList/classListReducer';
7
9
  import { fetchBillPaySetupApproverView, fetchBillPaySetupApproverViewFailure, fetchBillPaySetupApproverViewSuccess, } from '../billPaySetupApproverViewReducer';
8
10
  export const fetchBillPaySetupApproverViewEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchBillPaySetupApproverView.match), switchMap((action) => {
9
11
  const { cacheOverride, useV3 } = action.payload;
10
- const { billPaySetupApproverViewState, approvalRuleState } = state$.value;
12
+ const { billPaySetupApproverViewState, approvalRuleState, classListState } = state$.value;
13
+ const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state$.value);
11
14
  const approvalRules = getApprovalRulesByIds(approvalRuleState, billPaySetupApproverViewState.approvalRuleIds);
15
+ const shouldFetchClassList = isAccountingClassesEnabled &&
16
+ (cacheOverride === true ||
17
+ (classListState.hasValidState() === false &&
18
+ classListState.fetchState !== 'In-Progress'));
12
19
  if (cacheOverride === true ||
13
20
  approvalRules.length !==
14
21
  billPaySetupApproverViewState.approvalRuleIds.length ||
@@ -28,6 +35,9 @@ export const fetchBillPaySetupApproverViewEpic = (actions$, state$, zeniAPI) =>
28
35
  updateApprovalRules(response.data.approval_rules),
29
36
  fetchBillPaySetupApproverViewSuccess(approvalRuleIds),
30
37
  ];
38
+ if (shouldFetchClassList) {
39
+ actions.push(fetchClassList());
40
+ }
31
41
  return from(actions);
32
42
  }
33
43
  else {
@@ -37,6 +47,12 @@ export const fetchBillPaySetupApproverViewEpic = (actions$, state$, zeniAPI) =>
37
47
  }
38
48
  else {
39
49
  const { approvalRuleIds } = billPaySetupApproverViewState;
40
- return of(fetchBillPaySetupApproverViewSuccess(approvalRuleIds));
50
+ const actions = [
51
+ fetchBillPaySetupApproverViewSuccess(approvalRuleIds),
52
+ ];
53
+ if (shouldFetchClassList) {
54
+ actions.push(fetchClassList());
55
+ }
56
+ return from(actions);
41
57
  }
42
58
  }));
@@ -21,7 +21,6 @@ export const initializeBillPaySetupApproverViewUpdateDataEpic = (actions$, state
21
21
  name: approvalRule.name,
22
22
  description: approvalRule.description,
23
23
  separationOfDuties: approvalRule.separationOfDuties,
24
- isFallback: approvalRule.isFallback,
25
24
  };
26
25
  fetchActions.push(clearBillPaySetupApproverViewUpdateData(), saveBillPaySetupApproverViewUpdateData(billPaySetupApproverViewUpdateData));
27
26
  }
@@ -86,9 +86,6 @@ export const toApprovalChangableInfoPayload = (approverViewUpdateData) => {
86
86
  payload.is_separation_of_duty_enabled =
87
87
  approverViewUpdateData.separationOfDuties;
88
88
  }
89
- if (approverViewUpdateData.isFallback != null) {
90
- payload.is_fallback = approverViewUpdateData.isFallback;
91
- }
92
89
  if (isUpdate) {
93
90
  payload.approval_rule_id = approverViewUpdateData.approvalRuleId;
94
91
  }