@zeniai/client-epic-state 5.2.13 → 5.2.14-betaRD1

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 (135) hide show
  1. package/lib/entity/approvalRule/approvalRuleConflict.d.ts +13 -0
  2. package/lib/entity/approvalRule/approvalRuleConflict.js +16 -1
  3. package/lib/entity/jeSchedules/jeScheduleHelper.d.ts +1 -0
  4. package/lib/entity/jeSchedules/jeScheduleHelper.js +7 -0
  5. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +78 -1
  6. package/lib/entity/jeSchedules/jeSchedulesPayload.js +183 -4
  7. package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +4 -2
  8. package/lib/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  9. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +11 -2
  10. package/lib/entity/jeSchedules/jeSchedulesSelector.js +38 -3
  11. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +123 -1
  12. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +24 -1
  13. package/lib/entity/jeSchedules/jeSchedulesTypes.js +96 -1
  14. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  15. package/lib/entity/snackbar/snackbarTypes.js +3 -0
  16. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +2 -0
  17. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  18. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +2 -0
  19. package/lib/epic.d.ts +9 -1
  20. package/lib/epic.js +16 -0
  21. package/lib/esm/entity/approvalRule/approvalRuleConflict.js +16 -1
  22. package/lib/esm/entity/jeSchedules/jeScheduleHelper.js +6 -0
  23. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +183 -5
  24. package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +30 -2
  25. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +36 -2
  26. package/lib/esm/entity/jeSchedules/jeSchedulesTypes.js +86 -0
  27. package/lib/esm/entity/snackbar/snackbarTypes.js +3 -0
  28. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  29. package/lib/esm/epic.js +16 -0
  30. package/lib/esm/index.js +17 -11
  31. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  32. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +9 -1
  33. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +41 -5
  34. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +45 -0
  35. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  36. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +104 -0
  37. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  38. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +138 -0
  39. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +79 -0
  40. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +180 -0
  41. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +111 -0
  42. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +28 -0
  43. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +140 -0
  44. package/lib/esm/view/expenseAutomationView/payload/jeSchedulesPayload.js +55 -0
  45. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +319 -29
  46. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  47. package/lib/esm/view/expenseAutomationView/selectors/jeAccountSettingsViewSelector.js +1 -0
  48. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +106 -0
  49. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +327 -22
  50. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -6
  51. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +24 -7
  52. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +1 -1
  53. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +8 -1
  54. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +42 -8
  55. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogSubFamilyEpics.js +8 -2
  56. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +19 -10
  57. package/lib/esm/view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector.js +2 -0
  58. package/lib/esm/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +0 -1
  59. package/lib/esm/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +15 -36
  60. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  61. package/lib/esm/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  62. package/lib/esm/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  63. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +20 -1
  64. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewSelector.js +20 -1
  65. package/lib/index.d.ts +24 -18
  66. package/lib/index.js +93 -48
  67. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  68. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulePageEpic.js +9 -1
  69. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.d.ts +3 -2
  70. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +39 -3
  71. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.d.ts +21 -0
  72. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchOneTimeAccrualEpic.js +49 -0
  73. package/lib/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  74. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.d.ts +9 -0
  75. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +108 -0
  76. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  77. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +29 -0
  78. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +9 -0
  79. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +142 -0
  80. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  81. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +83 -0
  82. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.d.ts +13 -0
  83. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +187 -0
  84. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.d.ts +65 -0
  85. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +115 -0
  86. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +6 -0
  87. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +32 -0
  88. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +36 -0
  89. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +145 -0
  90. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  91. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +86 -3
  92. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.js +58 -1
  93. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +93 -12
  94. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +321 -29
  95. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -1
  96. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +2 -2
  97. package/lib/view/expenseAutomationView/selectorTypes/jeAccountSettingsViewSelectorTypes.d.ts +1 -0
  98. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +42 -0
  99. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  100. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +41 -7
  101. package/lib/view/expenseAutomationView/selectors/jeAccountSettingsViewSelector.js +1 -0
  102. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +21 -0
  103. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +112 -0
  104. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +34 -0
  105. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +335 -21
  106. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +1 -1
  107. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +83 -8
  108. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -8
  109. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +1 -1
  110. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.d.ts +13 -21
  111. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/catalogDetailEditPayload.js +24 -7
  112. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.d.ts +7 -0
  113. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +4 -3
  114. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.d.ts +18 -9
  115. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewReducer.js +9 -2
  116. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.d.ts +15 -5
  117. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector.js +43 -8
  118. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewState.d.ts +24 -0
  119. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogSubFamilyEpics.d.ts +1 -1
  120. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/invoicingCatalogSubFamilyEpics.js +8 -2
  121. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +18 -9
  122. package/lib/view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector.d.ts +6 -0
  123. package/lib/view/invoicing/invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewSelector.js +2 -0
  124. package/lib/view/invoicing/invoicingQboView/epics/fetchInvoicingAccountingPickersEpic.js +0 -1
  125. package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.d.ts +13 -13
  126. package/lib/view/invoicing/invoicingQboView/invoicingQboViewSelector.js +17 -38
  127. package/lib/view/scheduleView/scheduleListView/epics/fetchAccruedScheduleListEpic.js +1 -1
  128. package/lib/view/scheduleView/scheduleListView/epics/fetchDownloadSchedulesEpic.js +7 -2
  129. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.d.ts +4 -2
  130. package/lib/view/scheduleView/scheduleListView/scheduleListReducer.js +5 -3
  131. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector.js +20 -1
  132. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelectorTypes.d.ts +3 -0
  133. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewSelector.js +20 -1
  134. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewSelectorTypes.d.ts +3 -0
  135. package/package.json +1 -1
@@ -1,25 +1,9 @@
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, InvoicingCatalogItemFormTier } from './editInvoicingCatalogItemDetailViewState';
5
- export type CatalogDetailSubFamilyEditValues = InvoicingCatalogItemFormSubFamily;
6
- export interface CatalogDetailEditValues {
7
- applicableItems: string[];
8
- description: string;
9
- enabledForCheckout: boolean;
10
- enabledInPortal: boolean;
11
- giftClaimRedirectUrl: string;
12
- includedInMrr: boolean;
13
- isGiftable: boolean;
14
- isShippable: boolean;
15
- itemApplicability: string;
16
- metered: boolean;
17
- name: string;
18
- productCode: string;
19
- subFamilies: CatalogDetailSubFamilyEditValues[];
20
- unit: string;
21
- usageCalculation: string;
22
- }
4
+ import { type InvoicingCatalogAccountingLookup } from './editInvoicingCatalogItemDetailViewPayload';
5
+ import type { CatalogDetailEditValues, InvoicingCatalogItemFormTier } from './editInvoicingCatalogItemDetailViewState';
6
+ export type { CatalogDetailEditValues } from './editInvoicingCatalogItemDetailViewState';
23
7
  export interface CatalogDetailProductUpdate {
24
8
  data: Record<string, unknown>;
25
9
  id: string;
@@ -30,18 +14,26 @@ export interface CatalogDetailSavePayload {
30
14
  }
31
15
  /** Build default inline-edit form values from a loaded catalog item. */
32
16
  export declare const planToCatalogDetailEditValues: (plan: InvoicingPlan) => CatalogDetailEditValues;
33
- export declare const catalogDetailEditValuesToSavePayload: (values: CatalogDetailEditValues, itemType?: string, originalSubFamilies?: readonly InvoicingProduct[]) => CatalogDetailSavePayload;
17
+ export declare const catalogDetailEditValuesToSavePayload: (values: CatalogDetailEditValues, lookup: InvoicingCatalogAccountingLookup, itemType?: string, originalSubFamilies?: readonly InvoicingProduct[]) => CatalogDetailSavePayload;
34
18
  export interface CreateSubFamilyFormValues {
19
+ /** The QuickBooks class id the price point posts to. */
20
+ accountingCategory: string;
21
+ /** The QuickBooks income account id the price point posts to. */
22
+ accountingCode: string;
35
23
  billingCycles: string;
36
24
  description: string;
37
25
  freeQuantity: string;
38
26
  invoiceNotes: string;
27
+ isTaxable: boolean;
39
28
  name: string;
40
29
  period: string;
41
30
  periodUnit: string;
42
31
  priceCode: string;
43
32
  pricingModel: string;
44
33
  prorationType: string;
34
+ showDescriptionInInvoices: boolean;
35
+ showDescriptionInQuotes: boolean;
36
+ sku: string;
45
37
  trialEndAction: string;
46
38
  trialPeriod: string;
47
39
  trialPeriodUnit: string;
@@ -50,5 +42,5 @@ export interface CreateSubFamilyFormValues {
50
42
  tiers?: InvoicingCatalogItemFormTier[];
51
43
  }
52
44
  /** Build POST /catalog/products body for Create sub-family. */
53
- export declare const createSubFamilyFormToPayload: (itemId: string, itemType: string, values: CreateSubFamilyFormValues) => Record<string, unknown>;
45
+ export declare const createSubFamilyFormToPayload: (itemId: string, itemType: string, values: CreateSubFamilyFormValues, lookup: InvoicingCatalogAccountingLookup) => Record<string, unknown>;
54
46
  export declare const productToCreateSubFamilyFormValues: (product?: InvoicingProduct) => CreateSubFamilyFormValues;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.productToCreateSubFamilyFormValues = exports.createSubFamilyFormToPayload = exports.catalogDetailEditValuesToSavePayload = exports.planToCatalogDetailEditValues = void 0;
4
+ const editInvoicingCatalogItemDetailViewPayload_1 = require("./editInvoicingCatalogItemDetailViewPayload");
4
5
  const invoicingCatalogItemFormConfig_1 = require("./invoicingCatalogItemFormConfig");
5
6
  const trimOrUndefined = (value) => value.trim() !== '' ? value.trim() : undefined;
6
7
  const trimOrNull = (value) => value.trim() !== '' ? value.trim() : null;
@@ -39,7 +40,7 @@ const tierToPayload = (tier) => ({
39
40
  pricing_type: tier.pricingType,
40
41
  starting_unit: Number(tier.startingUnit) || 1,
41
42
  });
42
- const subFamilyToProductUpdate = (subFamily, itemType) => {
43
+ const subFamilyToProductUpdate = (subFamily, itemType, lookup) => {
43
44
  const tiered = (0, invoicingCatalogItemFormConfig_1.isTieredCatalogPricingModel)(subFamily.pricingModel);
44
45
  const data = {
45
46
  billing_cycles: hasValue(subFamily.billingCycles)
@@ -66,9 +67,12 @@ const subFamilyToProductUpdate = (subFamily, itemType) => {
66
67
  if (itemType === 'addon') {
67
68
  data.proration_type = subFamily.prorationType;
68
69
  }
70
+ // `null` rather than omitted when empty: an absent key on an update reads as
71
+ // "leave it alone", so a cleared account or class could never be saved.
72
+ data.accounting_detail = (0, editInvoicingCatalogItemDetailViewPayload_1.buildAccountingDetail)(subFamily, lookup) ?? null;
69
73
  return { data, id: subFamily.id };
70
74
  };
71
- const catalogDetailEditValuesToSavePayload = (values, itemType = 'plan', originalSubFamilies) => {
75
+ const catalogDetailEditValuesToSavePayload = (values, lookup, itemType = 'plan', originalSubFamilies) => {
72
76
  const planData = {
73
77
  applicable_items: values.itemApplicability === 'restricted' ? values.applicableItems : [],
74
78
  enabled_for_checkout: values.enabledForCheckout,
@@ -100,12 +104,12 @@ const catalogDetailEditValuesToSavePayload = (values, itemType = 'plan', origina
100
104
  planData.unit = unit;
101
105
  }
102
106
  const productUpdates = values.subFamilies.flatMap((subFamily) => {
103
- const update = subFamilyToProductUpdate(subFamily, itemType);
107
+ const update = subFamilyToProductUpdate(subFamily, itemType, lookup);
104
108
  const original = originalSubFamilies?.find((product) => product.id === subFamily.id);
105
109
  if (original == null) {
106
110
  return [update];
107
111
  }
108
- const originalUpdate = subFamilyToProductUpdate(subFamilyToEditValues(original), itemType);
112
+ const originalUpdate = subFamilyToProductUpdate(subFamilyToEditValues(original), itemType, lookup);
109
113
  const changedData = Object.fromEntries(Object.entries(update.data).filter(([key, value]) => JSON.stringify(value) !== JSON.stringify(originalUpdate.data[key])));
110
114
  return Object.keys(changedData).length > 0
111
115
  ? [{ data: changedData, id: update.id }]
@@ -118,21 +122,28 @@ const catalogDetailEditValuesToSavePayload = (values, itemType = 'plan', origina
118
122
  };
119
123
  exports.catalogDetailEditValuesToSavePayload = catalogDetailEditValuesToSavePayload;
120
124
  /** Build POST /catalog/products body for Create sub-family. */
121
- const createSubFamilyFormToPayload = (itemId, itemType, values) => {
125
+ const createSubFamilyFormToPayload = (itemId, itemType, values, lookup) => {
122
126
  const name = values.name.trim();
123
127
  const priceCode = trimOrUndefined(values.priceCode) ?? toProductCode(name);
124
128
  const tiered = (0, invoicingCatalogItemFormConfig_1.isTieredCatalogPricingModel)(values.pricingModel);
125
129
  const payload = {
126
130
  currency_code: 'USD',
127
131
  free_quantity: Number(values.freeQuantity) || 0,
128
- is_taxable: true,
132
+ is_taxable: values.isTaxable,
129
133
  item_id: itemId,
130
134
  name,
131
135
  price: tiered ? 0 : (values.priceDollars?.amount ?? 0),
132
136
  price_code: priceCode,
133
137
  pricing_model: values.pricingModel || 'flat_fee',
134
- show_description_in_invoices: true,
138
+ show_description_in_invoices: values.showDescriptionInInvoices,
139
+ show_description_in_quotes: values.showDescriptionInQuotes,
135
140
  };
141
+ // The same accounting body the item payload sends, so a price point created
142
+ // from the dialog carries the account and class the form would have given it.
143
+ const accountingDetail = (0, editInvoicingCatalogItemDetailViewPayload_1.buildAccountingDetail)(values, lookup);
144
+ if (accountingDetail != null) {
145
+ payload.accounting_detail = accountingDetail;
146
+ }
136
147
  if (tiered) {
137
148
  payload.tiers = (values.tiers ?? []).map(tierToPayload);
138
149
  }
@@ -163,10 +174,13 @@ const createSubFamilyFormToPayload = (itemId, itemType, values) => {
163
174
  };
164
175
  exports.createSubFamilyFormToPayload = createSubFamilyFormToPayload;
165
176
  const productToCreateSubFamilyFormValues = (product) => ({
177
+ accountingCategory: product?.accountingDetail?.accountingCategory1 ?? '',
178
+ accountingCode: product?.accountingDetail?.accountingCode ?? '',
166
179
  billingCycles: product?.billingCycles != null ? String(product.billingCycles) : '',
167
180
  description: product?.description ?? '',
168
181
  freeQuantity: product?.freeQuantity != null ? String(product.freeQuantity) : '0',
169
182
  invoiceNotes: product?.invoiceNotes ?? '',
183
+ isTaxable: product?.isTaxable ?? true,
170
184
  name: product?.name != null ? `${product.name} (copy)` : '',
171
185
  period: product?.period != null ? String(product.period) : '1',
172
186
  periodUnit: product?.periodUnit ?? 'month',
@@ -174,6 +188,9 @@ const productToCreateSubFamilyFormValues = (product) => ({
174
188
  priceDollars: product?.price,
175
189
  pricingModel: product?.pricingModel ?? 'flat_fee',
176
190
  prorationType: product?.prorationType ?? 'site_default',
191
+ showDescriptionInInvoices: product?.showDescriptionInInvoices ?? true,
192
+ showDescriptionInQuotes: product?.showDescriptionInQuotes ?? false,
193
+ sku: product?.accountingDetail?.sku ?? '',
177
194
  trialEndAction: product?.trialEndAction ?? 'site_default',
178
195
  trialPeriod: product?.trialPeriod != null ? String(product.trialPeriod) : '',
179
196
  trialPeriodUnit: product?.trialPeriodUnit ?? 'day',
@@ -13,6 +13,13 @@ export interface InvoicingCatalogAccountingLookup {
13
13
  accountByQboId: (qboId: string) => AccountBase | undefined;
14
14
  classByQboId: (qboId: string) => ClassBase | undefined;
15
15
  }
16
+ /** The accounting fields any price-point form collects. */
17
+ export interface InvoicingCatalogAccountingFields {
18
+ accountingCategory: string;
19
+ accountingCode: string;
20
+ sku: string;
21
+ }
22
+ export declare const buildAccountingDetail: (subFamily: InvoicingCatalogAccountingFields, lookup: InvoicingCatalogAccountingLookup) => Record<string, unknown> | undefined;
16
23
  /**
17
24
  * Build the parent catalog-item request body from the form draft. Creates omit
18
25
  * both parent and sub-family IDs; edits retain returned sub-family IDs.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.localDataToSaveInvoicingCatalogItemPayload = void 0;
3
+ exports.localDataToSaveInvoicingCatalogItemPayload = exports.buildAccountingDetail = void 0;
4
4
  const accountPayload_1 = require("../../../entity/account/accountPayload");
5
5
  const classPayload_1 = require("../../../entity/class/classPayload");
6
6
  const invoicingCatalogItemFormConfig_1 = require("./invoicingCatalogItemFormConfig");
@@ -31,6 +31,7 @@ const buildAccountingDetail = (subFamily, lookup) => {
31
31
  }
32
32
  return Object.keys(detail).length > 0 ? detail : undefined;
33
33
  };
34
+ exports.buildAccountingDetail = buildAccountingDetail;
34
35
  const buildSubFamilyPayload = (localData, subFamily, clearEmptyValues, lookup) => {
35
36
  const isAddon = localData.catalogType === 'addon';
36
37
  const tiered = (0, invoicingCatalogItemFormConfig_1.isTieredCatalogPricingModel)(subFamily.pricingModel);
@@ -85,7 +86,7 @@ const buildSubFamilyPayload = (localData, subFamily, clearEmptyValues, lookup) =
85
86
  starting_unit: Number(tier.startingUnit) || 1,
86
87
  }));
87
88
  }
88
- const accountingDetail = buildAccountingDetail(subFamily, lookup);
89
+ const accountingDetail = (0, exports.buildAccountingDetail)(subFamily, lookup);
89
90
  if (accountingDetail != null) {
90
91
  payload.accounting_detail = accountingDetail;
91
92
  }
@@ -142,7 +143,7 @@ const localDataToSaveInvoicingCatalogItemPayload = (localData, isCreate, lookup)
142
143
  // would make a cleared mapping impossible to save — the same reason
143
144
  // `description` and `invoice_notes` go through `trimOrNull`.
144
145
  detail.accounting_detail =
145
- buildAccountingDetail(subFamily, lookup) ?? null;
146
+ (0, exports.buildAccountingDetail)(subFamily, lookup) ?? null;
146
147
  const id = trimOrUndefined(subFamily.id);
147
148
  return id != null ? { ...detail, id } : detail;
148
149
  });
@@ -1,8 +1,8 @@
1
1
  import { ID } from '../../../commonStateTypes/common';
2
2
  import { ZeniAPIStatus } from '../../../responsePayload';
3
3
  import { InvoicingCatalogItemKind } from '../invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewState';
4
- import type { CatalogDetailProductUpdate } from './catalogDetailEditPayload';
5
- import { EditInvoicingCatalogItemDetailViewState, InvoicingCatalogItemFormLocalData } from './editInvoicingCatalogItemDetailViewState';
4
+ import type { CreateSubFamilyFormValues } from './catalogDetailEditPayload';
5
+ import { type CatalogDetailEditValues, EditInvoicingCatalogItemDetailViewState, InvoicingCatalogItemFormLocalData } from './editInvoicingCatalogItemDetailViewState';
6
6
  /** Push the full form draft into CES (edit tree when `id` is present). */
7
7
  export interface UpdateInvoicingCatalogItemFormDraftPayload {
8
8
  localData: InvoicingCatalogItemFormLocalData;
@@ -12,27 +12,36 @@ export interface UpdateInvoicingCatalogItemFormDraftPayload {
12
12
  export interface SubmitInvoicingCatalogItemFormPayload {
13
13
  id?: ID;
14
14
  }
15
+ /** Push the detail page's inline-edit draft into CES. */
16
+ export interface UpdateInvoicingCatalogItemDetailEditDraftPayload {
17
+ id: ID;
18
+ localData: CatalogDetailEditValues;
19
+ }
15
20
  /**
16
- * Data-based save used by the catalog detail-page inline edit (which builds its
17
- * own partial payload). The create/edit form flow uses the draft-based
18
- * `submitInvoicingCatalogItemForm` instead.
21
+ * Save the catalog detail page's inline edit. Carries no form data: the draft,
22
+ * the saved price points and the item type all come off state in the epic, so
23
+ * the page never has to hold or forward them.
19
24
  */
20
25
  export interface SaveInvoicingCatalogItemPayload {
21
- data: Record<string, unknown>;
22
26
  kind: InvoicingCatalogItemKind;
23
27
  id?: ID;
24
- productUpdates?: CatalogDetailProductUpdate[];
25
28
  }
26
29
  export interface CreateInvoicingCatalogSubFamilyPayload {
27
- data: Record<string, unknown>;
30
+ itemType: string;
28
31
  parentItemId: ID;
32
+ /**
33
+ * The dialog's form values. The request body is built in the epic, which can
34
+ * resolve a picked account id to the record the payload carries — the page
35
+ * holds ids and never needs to know the wire shape.
36
+ */
37
+ values: CreateSubFamilyFormValues;
29
38
  }
30
39
  export interface ArchiveInvoicingCatalogSubFamilyPayload {
31
40
  parentItemId: ID;
32
41
  subFamilyId: ID;
33
42
  }
34
43
  export declare const initialState: EditInvoicingCatalogItemDetailViewState;
35
- export declare const updateInvoicingCatalogItemFormDraft: import("@reduxjs/toolkit").ActionCreatorWithPayload<UpdateInvoicingCatalogItemFormDraftPayload, "editInvoicingCatalogItemDetailView/updateInvoicingCatalogItemFormDraft">, submitInvoicingCatalogItemForm: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: SubmitInvoicingCatalogItemFormPayload], SubmitInvoicingCatalogItemFormPayload, "editInvoicingCatalogItemDetailView/submitInvoicingCatalogItemForm", never, never>, saveInvoicingCatalogItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<SaveInvoicingCatalogItemPayload, "editInvoicingCatalogItemDetailView/saveInvoicingCatalogItem">, createInvoicingCatalogSubFamily: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: CreateInvoicingCatalogSubFamilyPayload], CreateInvoicingCatalogSubFamilyPayload, "editInvoicingCatalogItemDetailView/createInvoicingCatalogSubFamily", never, never>, archiveInvoicingCatalogSubFamily: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: ArchiveInvoicingCatalogSubFamilyPayload], ArchiveInvoicingCatalogSubFamilyPayload, "editInvoicingCatalogItemDetailView/archiveInvoicingCatalogSubFamily", never, never>, submitInvoicingCatalogItemFormSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
44
+ export declare const updateInvoicingCatalogItemDetailEditDraft: import("@reduxjs/toolkit").ActionCreatorWithPayload<UpdateInvoicingCatalogItemDetailEditDraftPayload, "editInvoicingCatalogItemDetailView/updateInvoicingCatalogItemDetailEditDraft">, updateInvoicingCatalogItemFormDraft: import("@reduxjs/toolkit").ActionCreatorWithPayload<UpdateInvoicingCatalogItemFormDraftPayload, "editInvoicingCatalogItemDetailView/updateInvoicingCatalogItemFormDraft">, submitInvoicingCatalogItemForm: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: SubmitInvoicingCatalogItemFormPayload], SubmitInvoicingCatalogItemFormPayload, "editInvoicingCatalogItemDetailView/submitInvoicingCatalogItemForm", never, never>, saveInvoicingCatalogItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<SaveInvoicingCatalogItemPayload, "editInvoicingCatalogItemDetailView/saveInvoicingCatalogItem">, createInvoicingCatalogSubFamily: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: CreateInvoicingCatalogSubFamilyPayload], CreateInvoicingCatalogSubFamilyPayload, "editInvoicingCatalogItemDetailView/createInvoicingCatalogSubFamily", never, never>, archiveInvoicingCatalogSubFamily: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[payload: ArchiveInvoicingCatalogSubFamilyPayload], ArchiveInvoicingCatalogSubFamilyPayload, "editInvoicingCatalogItemDetailView/archiveInvoicingCatalogSubFamily", never, never>, submitInvoicingCatalogItemFormSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
36
45
  itemId: ID;
37
46
  kind: InvoicingCatalogItemKind;
38
47
  }, "editInvoicingCatalogItemDetailView/submitInvoicingCatalogItemFormSuccess">, submitInvoicingCatalogItemFormFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "editInvoicingCatalogItemDetailView/submitInvoicingCatalogItemFormFailure">, resetEditInvoicingCatalogItemDetailView: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"editInvoicingCatalogItemDetailView/resetEditInvoicingCatalogItemDetailView">;
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.resetEditInvoicingCatalogItemDetailView = exports.submitInvoicingCatalogItemFormFailure = exports.submitInvoicingCatalogItemFormSuccess = exports.archiveInvoicingCatalogSubFamily = exports.createInvoicingCatalogSubFamily = exports.saveInvoicingCatalogItem = exports.submitInvoicingCatalogItemForm = exports.updateInvoicingCatalogItemFormDraft = exports.initialState = void 0;
4
+ exports.resetEditInvoicingCatalogItemDetailView = exports.submitInvoicingCatalogItemFormFailure = exports.submitInvoicingCatalogItemFormSuccess = exports.archiveInvoicingCatalogSubFamily = exports.createInvoicingCatalogSubFamily = exports.saveInvoicingCatalogItem = exports.submitInvoicingCatalogItemForm = exports.updateInvoicingCatalogItemFormDraft = exports.updateInvoicingCatalogItemDetailEditDraft = exports.initialState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const rootActions_1 = require("../../../rootActions");
7
7
  const invoicingCatalogItemFormConfig_1 = require("./invoicingCatalogItemFormConfig");
8
8
  exports.initialState = {
9
9
  fetchState: 'Not-Started',
10
10
  error: undefined,
11
+ detailEditDraftById: {},
11
12
  editDraftById: {},
12
13
  newItemDraft: { ...invoicingCatalogItemFormConfig_1.initialInvoicingCatalogItemFormLocalData },
13
14
  savedItemId: undefined,
@@ -29,6 +30,10 @@ const editInvoicingCatalogItemDetailView = (0, toolkit_1.createSlice)({
29
30
  draft.newItemDraft = localData;
30
31
  }
31
32
  },
33
+ updateInvoicingCatalogItemDetailEditDraft(draft, action) {
34
+ const { id, localData } = action.payload;
35
+ draft.detailEditDraftById[id] = localData;
36
+ },
32
37
  submitInvoicingCatalogItemForm: {
33
38
  reducer(draft) {
34
39
  draft.fetchState = 'In-Progress';
@@ -70,6 +75,7 @@ const editInvoicingCatalogItemDetailView = (0, toolkit_1.createSlice)({
70
75
  draft.error = undefined;
71
76
  draft.savedItemId = action.payload.itemId;
72
77
  draft.savedKind = action.payload.kind;
78
+ delete draft.detailEditDraftById[action.payload.itemId];
73
79
  },
74
80
  submitInvoicingCatalogItemFormFailure(draft, action) {
75
81
  draft.fetchState = 'Error';
@@ -80,6 +86,7 @@ const editInvoicingCatalogItemDetailView = (0, toolkit_1.createSlice)({
80
86
  draft.error = undefined;
81
87
  draft.savedItemId = undefined;
82
88
  draft.savedKind = undefined;
89
+ draft.detailEditDraftById = {};
83
90
  draft.editDraftById = {};
84
91
  draft.newItemDraft = { ...invoicingCatalogItemFormConfig_1.initialInvoicingCatalogItemFormLocalData };
85
92
  },
@@ -90,5 +97,5 @@ const editInvoicingCatalogItemDetailView = (0, toolkit_1.createSlice)({
90
97
  });
91
98
  },
92
99
  });
93
- _a = editInvoicingCatalogItemDetailView.actions, exports.updateInvoicingCatalogItemFormDraft = _a.updateInvoicingCatalogItemFormDraft, exports.submitInvoicingCatalogItemForm = _a.submitInvoicingCatalogItemForm, exports.saveInvoicingCatalogItem = _a.saveInvoicingCatalogItem, exports.createInvoicingCatalogSubFamily = _a.createInvoicingCatalogSubFamily, exports.archiveInvoicingCatalogSubFamily = _a.archiveInvoicingCatalogSubFamily, exports.submitInvoicingCatalogItemFormSuccess = _a.submitInvoicingCatalogItemFormSuccess, exports.submitInvoicingCatalogItemFormFailure = _a.submitInvoicingCatalogItemFormFailure, exports.resetEditInvoicingCatalogItemDetailView = _a.resetEditInvoicingCatalogItemDetailView;
100
+ _a = editInvoicingCatalogItemDetailView.actions, exports.updateInvoicingCatalogItemDetailEditDraft = _a.updateInvoicingCatalogItemDetailEditDraft, exports.updateInvoicingCatalogItemFormDraft = _a.updateInvoicingCatalogItemFormDraft, exports.submitInvoicingCatalogItemForm = _a.submitInvoicingCatalogItemForm, exports.saveInvoicingCatalogItem = _a.saveInvoicingCatalogItem, exports.createInvoicingCatalogSubFamily = _a.createInvoicingCatalogSubFamily, exports.archiveInvoicingCatalogSubFamily = _a.archiveInvoicingCatalogSubFamily, exports.submitInvoicingCatalogItemFormSuccess = _a.submitInvoicingCatalogItemFormSuccess, exports.submitInvoicingCatalogItemFormFailure = _a.submitInvoicingCatalogItemFormFailure, exports.resetEditInvoicingCatalogItemDetailView = _a.resetEditInvoicingCatalogItemDetailView;
94
101
  exports.default = editInvoicingCatalogItemDetailView.reducer;
@@ -6,7 +6,16 @@ import { InvoicingFieldHelpByCode, InvoicingNamedOption, InvoicingNamedOptionsBy
6
6
  import { InvoicingPlan } from '../../../entity/invoicing/plan/planState';
7
7
  import { RootState } from '../../../rootStateTypes';
8
8
  import { InvoicingCatalogItemKind } from '../invoicingCatalogItemDetailView/invoicingCatalogItemDetailViewState';
9
- import { InvoicingCatalogItemFormLocalData } from './editInvoicingCatalogItemDetailViewState';
9
+ import { type CatalogDetailEditValues, InvoicingCatalogItemFormLocalData } from './editInvoicingCatalogItemDetailViewState';
10
+ /** An unsaved item's inline-edit draft, before the record has loaded. */
11
+ export declare const initialCatalogDetailEditValues: () => CatalogDetailEditValues;
12
+ /**
13
+ * The detail page's inline-edit form data: the stored draft once the user has
14
+ * touched the form, seeded from the loaded record until then. Memoized so the
15
+ * page receives a stable value — recomputing it per store change would reseed
16
+ * the form mid-edit and drop what the user had typed.
17
+ */
18
+ export declare const getInvoicingCatalogItemDetailEditLocalData: (state: RootState, id: ID | undefined) => CatalogDetailEditValues;
10
19
  export declare const getEditInvoicingCatalogItemDetailViewState: (state: RootState) => FetchStateAndError;
11
20
  export declare const getSavedInvoicingCatalogItemId: (state: RootState) => ID | undefined;
12
21
  export declare const getSavedInvoicingCatalogItemKind: (state: RootState) => InvoicingCatalogItemKind | undefined;
@@ -48,12 +57,13 @@ export interface InvoicingCatalogItemFormView extends SelectorView {
48
57
  pricingModelValues: readonly string[];
49
58
  prorationValues: readonly string[];
50
59
  /**
51
- * Account and class trees for the price-point pickers, already narrowed to the
52
- * income accounts a price may post to. Empty until QBO is connected — the form
53
- * must not offer a mapping that cannot be pushed.
60
+ * Account and class trees for the price-point pickers, straight from the
61
+ * shared accounting lists — the pickers drop the nodes they cannot submit.
62
+ * Empty until QBO is connected: the form must not offer a mapping that cannot
63
+ * be pushed.
54
64
  */
65
+ qboAccountHierarchy: NestedAccountHierarchyForReport[];
55
66
  qboClassHierarchy: NestedClassHierarchyForReport[];
56
- qboIncomeAccountHierarchy: NestedAccountHierarchyForReport[];
57
67
  tierTypeValues: readonly string[];
58
68
  trialEndActionOptions: InvoicingNamedOption[];
59
69
  trialUnitOptions: InvoicingNamedOption[];
@@ -1,11 +1,48 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getInvoicingCatalogItemFormView = exports.getInvoicingApplicableCatalogItemOptions = exports.getSavedInvoicingCatalogItemKind = exports.getSavedInvoicingCatalogItemId = exports.getEditInvoicingCatalogItemDetailViewState = void 0;
3
+ exports.getInvoicingCatalogItemFormView = exports.getInvoicingApplicableCatalogItemOptions = exports.getSavedInvoicingCatalogItemKind = exports.getSavedInvoicingCatalogItemId = exports.getEditInvoicingCatalogItemDetailViewState = exports.getInvoicingCatalogItemDetailEditLocalData = exports.initialCatalogDetailEditValues = void 0;
4
4
  const toolkit_1 = require("@reduxjs/toolkit");
5
5
  const planSelector_1 = require("../../../entity/invoicing/plan/planSelector");
6
6
  const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
7
7
  const invoicingQboViewSelector_1 = require("../invoicingQboView/invoicingQboViewSelector");
8
+ const catalogDetailEditPayload_1 = require("./catalogDetailEditPayload");
8
9
  const invoicingCatalogItemFormConfig_1 = require("./invoicingCatalogItemFormConfig");
10
+ /** An unsaved item's inline-edit draft, before the record has loaded. */
11
+ const initialCatalogDetailEditValues = () => ({
12
+ applicableItems: [],
13
+ description: '',
14
+ enabledForCheckout: true,
15
+ enabledInPortal: true,
16
+ giftClaimRedirectUrl: '',
17
+ includedInMrr: true,
18
+ isGiftable: false,
19
+ isShippable: false,
20
+ itemApplicability: 'all',
21
+ metered: false,
22
+ name: '',
23
+ productCode: '',
24
+ subFamilies: [],
25
+ unit: '',
26
+ usageCalculation: 'sum_of_usages',
27
+ });
28
+ exports.initialCatalogDetailEditValues = initialCatalogDetailEditValues;
29
+ /**
30
+ * The detail page's inline-edit form data: the stored draft once the user has
31
+ * touched the form, seeded from the loaded record until then. Memoized so the
32
+ * page receives a stable value — recomputing it per store change would reseed
33
+ * the form mid-edit and drop what the user had typed.
34
+ */
35
+ exports.getInvoicingCatalogItemDetailEditLocalData = (0, toolkit_1.createSelector)([
36
+ (state, id) => id != null
37
+ ? state.editInvoicingCatalogItemDetailViewState.detailEditDraftById[id]
38
+ : undefined,
39
+ (state, id) => id != null
40
+ ? (0, planSelector_1.getInvoicingPlanById)(state.invoicingPlanState, id)
41
+ : undefined,
42
+ ], (storedDraft, plan) => storedDraft ??
43
+ (plan != null
44
+ ? (0, catalogDetailEditPayload_1.planToCatalogDetailEditValues)(plan)
45
+ : (0, exports.initialCatalogDetailEditValues)()));
9
46
  const getEditInvoicingCatalogItemDetailViewState = (state) => ({
10
47
  fetchState: state.editInvoicingCatalogItemDetailViewState.fetchState,
11
48
  error: state.editInvoicingCatalogItemDetailViewState.error,
@@ -55,17 +92,15 @@ const getInvoicingCatalogItemFormView = (state, id) => {
55
92
  const applicableItemOptions = id != null
56
93
  ? allApplicableItemOptions.filter((option) => option.id !== id)
57
94
  : allApplicableItemOptions;
58
- const isQboConnected = (0, invoicingQboViewSelector_1.isInvoicingQboConnected)(state);
95
+ const qboView = (0, invoicingQboViewSelector_1.isInvoicingQboConnected)(state)
96
+ ? (0, invoicingQboViewSelector_1.getInvoicingQboView)(state)
97
+ : undefined;
59
98
  const { billingPeriodUnitOptions, catalogItemTypeOptions, catalogTierTypeOptionsByPricingModel, catalogTrialEndActionOptions, catalogTrialUnitOptions, } = (0, invoicingConfigViewSelector_1.getInvoicingConfigView)(state);
60
99
  return {
61
100
  fieldHelp: (0, invoicingConfigViewSelector_1.invoicingFieldHelpForGroup)(state, 'catalog'),
62
101
  isQboPickerDataLoading: (0, invoicingQboViewSelector_1.isInvoicingAccountingPickerDataLoading)(state),
63
- qboClassHierarchy: isQboConnected
64
- ? (0, invoicingQboViewSelector_1.getInvoicingQboView)(state).nestedClassHierarchy
65
- : [],
66
- qboIncomeAccountHierarchy: isQboConnected
67
- ? (0, invoicingQboViewSelector_1.invoicingAccountHierarchyForTypes)(state, invoicingQboViewSelector_1.INVOICING_INCOME_ACCOUNT_TYPES)
68
- : [],
102
+ qboAccountHierarchy: qboView?.nestedAccountHierarchy ?? [],
103
+ qboClassHierarchy: qboView?.nestedClassHierarchy ?? [],
69
104
  applicabilityValues: invoicingCatalogItemFormConfig_1.INVOICING_CATALOG_APPLICABILITY_VALUES,
70
105
  applicableItemOptions,
71
106
  localData,
@@ -55,7 +55,31 @@ export interface InvoicingCatalogItemFormLocalData {
55
55
  subFamilies: InvoicingCatalogItemFormSubFamily[];
56
56
  unit: string;
57
57
  }
58
+ /**
59
+ * Draft form state for the detail page's inline edit. Separate from
60
+ * {@link InvoicingCatalogItemFormLocalData}: the inline editor exposes the
61
+ * portal/checkout/gifting fields the create form does not.
62
+ */
63
+ export interface CatalogDetailEditValues {
64
+ applicableItems: string[];
65
+ description: string;
66
+ enabledForCheckout: boolean;
67
+ enabledInPortal: boolean;
68
+ giftClaimRedirectUrl: string;
69
+ includedInMrr: boolean;
70
+ isGiftable: boolean;
71
+ isShippable: boolean;
72
+ itemApplicability: string;
73
+ metered: boolean;
74
+ name: string;
75
+ productCode: string;
76
+ subFamilies: InvoicingCatalogItemFormSubFamily[];
77
+ unit: string;
78
+ usageCalculation: string;
79
+ }
58
80
  export interface EditInvoicingCatalogItemDetailViewState extends FetchedState {
81
+ /** Inline-edit drafts, keyed by catalog item id. */
82
+ detailEditDraftById: Record<ID, CatalogDetailEditValues>;
59
83
  editDraftById: Record<ID, InvoicingCatalogItemFormLocalData>;
60
84
  newItemDraft: InvoicingCatalogItemFormLocalData;
61
85
  savedItemId?: ID;
@@ -5,5 +5,5 @@ import { RootState } from '../../../rootStateTypes';
5
5
  import { ZeniAPI } from '../../../zeniAPI';
6
6
  import { archiveInvoicingCatalogSubFamily, createInvoicingCatalogSubFamily, submitInvoicingCatalogItemFormFailure, submitInvoicingCatalogItemFormSuccess } from './editInvoicingCatalogItemDetailViewReducer';
7
7
  export type ActionType = ReturnType<typeof createInvoicingCatalogSubFamily> | ReturnType<typeof archiveInvoicingCatalogSubFamily> | ReturnType<typeof mergeInvoicingPlanSubFamily> | ReturnType<typeof submitInvoicingCatalogItemFormSuccess> | ReturnType<typeof submitInvoicingCatalogItemFormFailure>;
8
- export declare const createInvoicingCatalogSubFamilyEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
8
+ export declare const createInvoicingCatalogSubFamilyEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
9
9
  export declare const archiveInvoicingCatalogSubFamilyEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -5,6 +5,8 @@ const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
6
  const planReducer_1 = require("../../../entity/invoicing/plan/planReducer");
7
7
  const responsePayload_1 = require("../../../responsePayload");
8
+ const invoicingQboViewSelector_1 = require("../invoicingQboView/invoicingQboViewSelector");
9
+ const catalogDetailEditPayload_1 = require("./catalogDetailEditPayload");
8
10
  const editInvoicingCatalogItemDetailViewReducer_1 = require("./editInvoicingCatalogItemDetailViewReducer");
9
11
  const subFamilySuccessActions = (parentItemId, subFamilyPayload) => [
10
12
  (0, planReducer_1.mergeInvoicingPlanSubFamily)(parentItemId, subFamilyPayload),
@@ -13,8 +15,12 @@ const subFamilySuccessActions = (parentItemId, subFamilyPayload) => [
13
15
  kind: 'plan',
14
16
  }),
15
17
  ];
16
- const createInvoicingCatalogSubFamilyEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(editInvoicingCatalogItemDetailViewReducer_1.createInvoicingCatalogSubFamily.match), (0, operators_1.mergeMap)((action) => {
17
- const { data, parentItemId } = action.payload;
18
+ const createInvoicingCatalogSubFamilyEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(editInvoicingCatalogItemDetailViewReducer_1.createInvoicingCatalogSubFamily.match), (0, operators_1.mergeMap)((action) => {
19
+ const { itemType, parentItemId, values } = action.payload;
20
+ const state = state$.value;
21
+ // Built here so the dialog can stay in picked ids: resolving one to the
22
+ // account record the payload carries needs the shared account list.
23
+ const data = (0, catalogDetailEditPayload_1.createSubFamilyFormToPayload)(parentItemId, itemType, values, (0, invoicingQboViewSelector_1.getInvoicingCatalogAccountingLookup)(state));
18
24
  const baseUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0`;
19
25
  return zeniAPI
20
26
  .postAndGetJSON(`${baseUrl}/catalog/products`, data)
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.saveInvoicingCatalogItemEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
+ const planSelector_1 = require("../../../entity/invoicing/plan/planSelector");
6
7
  const planReducer_1 = require("../../../entity/invoicing/plan/planReducer");
7
8
  const productReducer_1 = require("../../../entity/invoicing/product/productReducer");
8
9
  const snackbarApiError_1 = require("../../../entity/snackbar/snackbarApiError");
@@ -10,25 +11,33 @@ const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
10
11
  const responsePayload_1 = require("../../../responsePayload");
11
12
  const invoicingCatalogListViewReducer_1 = require("../invoicingCatalogListView/invoicingCatalogListViewReducer");
12
13
  const invoicingQboViewSelector_1 = require("../invoicingQboView/invoicingQboViewSelector");
14
+ const catalogDetailEditPayload_1 = require("./catalogDetailEditPayload");
13
15
  const editInvoicingCatalogItemDetailViewPayload_1 = require("./editInvoicingCatalogItemDetailViewPayload");
16
+ const editInvoicingCatalogItemDetailViewSelector_1 = require("./editInvoicingCatalogItemDetailViewSelector");
14
17
  const editInvoicingCatalogItemDetailViewReducer_1 = require("./editInvoicingCatalogItemDetailViewReducer");
15
18
  const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)((action) => editInvoicingCatalogItemDetailViewReducer_1.submitInvoicingCatalogItemForm.match(action) ||
16
19
  editInvoicingCatalogItemDetailViewReducer_1.saveInvoicingCatalogItem.match(action)), (0, operators_1.mergeMap)((action) => {
17
20
  const { id } = action.payload;
18
- // Draft-based create/edit form vs. detail-page inline edit (raw data).
21
+ const state = state$.value;
22
+ const accountingLookup = (0, invoicingQboViewSelector_1.getInvoicingCatalogAccountingLookup)(state);
23
+ // Both sources are form values, turned into request bodies here so the
24
+ // picked account and class become the records the service stores: the
25
+ // detail page's edit form, or the create/edit form's draft.
19
26
  let data;
27
+ let editProductUpdates;
20
28
  if (editInvoicingCatalogItemDetailViewReducer_1.saveInvoicingCatalogItem.match(action)) {
21
- data = action.payload.data;
29
+ const plan = id != null
30
+ ? (0, planSelector_1.getInvoicingPlanById)(state.invoicingPlanState, id)
31
+ : undefined;
32
+ const savePayload = (0, catalogDetailEditPayload_1.catalogDetailEditValuesToSavePayload)((0, editInvoicingCatalogItemDetailViewSelector_1.getInvoicingCatalogItemDetailEditLocalData)(state, id), accountingLookup, plan?.type ?? plan?.itemType, plan?.subFamilies);
33
+ data = savePayload.planData;
34
+ editProductUpdates = savePayload.productUpdates;
22
35
  }
23
36
  else {
24
- const viewState = state$.value.editInvoicingCatalogItemDetailViewState;
37
+ const viewState = state.editInvoicingCatalogItemDetailViewState;
25
38
  const localData = (id != null ? viewState.editDraftById[id] : viewState.newItemDraft) ??
26
39
  viewState.newItemDraft;
27
- const state = state$.value;
28
- data = (0, editInvoicingCatalogItemDetailViewPayload_1.localDataToSaveInvoicingCatalogItemPayload)(localData, id == null, {
29
- accountByQboId: (qboId) => (0, invoicingQboViewSelector_1.invoicingQboAccountByQboId)(state, qboId),
30
- classByQboId: (qboId) => (0, invoicingQboViewSelector_1.invoicingQboClassByQboId)(state, qboId),
31
- });
40
+ data = (0, editInvoicingCatalogItemDetailViewPayload_1.localDataToSaveInvoicingCatalogItemPayload)(localData, id == null, accountingLookup);
32
41
  }
33
42
  const baseUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0`;
34
43
  const path = id != null
@@ -91,7 +100,7 @@ const saveInvoicingCatalogItemEpic = (actions$, state$, zeniAPI) => actions$.pip
91
100
  return resultActions;
92
101
  };
93
102
  const productUpdates = editInvoicingCatalogItemDetailViewReducer_1.saveInvoicingCatalogItem.match(action)
94
- ? (action.payload.productUpdates ?? [])
103
+ ? (editProductUpdates ?? [])
95
104
  : [];
96
105
  if (productUpdates.length === 0) {
97
106
  return completeSave([]);
@@ -3,6 +3,7 @@ import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndRep
3
3
  import { InvoicingCatalogItemLifecycleAction, InvoicingCatalogLifecycleActionOption, InvoicingCatalogProductLifecycleAction, InvoicingFieldHelpByCode, InvoicingNamedOption, InvoicingNamedOptionsByKey } from '../../../entity/invoicing/invoicingCommonPayload';
4
4
  import { InvoicingPlan } from '../../../entity/invoicing/plan/planState';
5
5
  import { RootState } from '../../../rootStateTypes';
6
+ import type { CatalogDetailEditValues } from '../editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewState';
6
7
  import { InvoicingCatalogItemKind } from './invoicingCatalogItemDetailViewState';
7
8
  /**
8
9
  * Read-only view for the catalog item (plan or product) detail page. One screen
@@ -20,6 +21,11 @@ export interface InvoicingCatalogItemDetailView extends SelectorView {
20
21
  catalogItemLifecycleActionOptions: InvoicingCatalogLifecycleActionOption<InvoicingCatalogItemLifecycleAction>[];
21
22
  catalogProductLifecycleActionOptions: InvoicingCatalogLifecycleActionOption<InvoicingCatalogProductLifecycleAction>[];
22
23
  configFetchState: FetchState;
24
+ /**
25
+ * The inline editor's form data, seeded from the loaded record and updated on
26
+ * every change, so the page renders from CES rather than from its own reset.
27
+ */
28
+ editLocalData: CatalogDetailEditValues;
23
29
  /**
24
30
  * Backend help copy for this screen's field group, keyed by field code.
25
31
  * Folded in here so the screen never reaches for the config view itself.
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getInvoicingCatalogItemDetail = void 0;
4
4
  const planSelector_1 = require("../../../entity/invoicing/plan/planSelector");
5
5
  const invoicingConfigViewSelector_1 = require("../invoicingConfigView/invoicingConfigViewSelector");
6
+ const editInvoicingCatalogItemDetailViewSelector_1 = require("../editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewSelector");
6
7
  const getInvoicingCatalogItemDetail = (state, _kind, id) => {
7
8
  const { error, fetchState } = state.invoicingCatalogItemDetailViewState;
8
9
  const { billingPeriodUnitOptions, catalogItemLifecycleActionOptions, catalogItemTypeOptions, catalogProductLifecycleActionOptions, catalogTierTypeOptionsByPricingModel, catalogTrialEndActionOptions, catalogTrialUnitOptions, fetchState: configFetchState, } = (0, invoicingConfigViewSelector_1.getInvoicingConfigView)(state);
@@ -13,6 +14,7 @@ const getInvoicingCatalogItemDetail = (state, _kind, id) => {
13
14
  catalogTierTypeOptionsByPricingModel,
14
15
  configFetchState,
15
16
  periodUnitOptions: billingPeriodUnitOptions,
17
+ editLocalData: (0, editInvoicingCatalogItemDetailViewSelector_1.getInvoicingCatalogItemDetailEditLocalData)(state, id),
16
18
  plan: (0, planSelector_1.getInvoicingPlanById)(state.invoicingPlanState, id),
17
19
  trialEndActionOptions: catalogTrialEndActionOptions,
18
20
  trialUnitOptions: catalogTrialUnitOptions,
@@ -21,7 +21,6 @@ const fetchInvoicingAccountingPickersEpic = (actions$, state$) => actions$.pipe(
21
21
  accountList.fetchState !== 'In-Progress') {
22
22
  // Same arguments the vendor and categorization screens pass, so this
23
23
  // shares their cached list rather than replacing it with a narrower one.
24
- // Invoicing narrows to income accounts when it builds its options.
25
24
  actions.push((0, accountListReducer_1.fetchAccountList)(invoicingQboViewSelector_1.INVOICING_ACCOUNT_LIST_KEY, true));
26
25
  }
27
26
  const classList = state.classListState;