@dainamite/cpq 0.5.0 → 0.6.0

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 (233) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/MIGRATION.md +74 -0
  3. package/dist/modules/cpq/acl.js +1 -0
  4. package/dist/modules/cpq/acl.js.map +2 -2
  5. package/dist/modules/cpq/api/_helpers/adjustmentCommandRoute.js +45 -0
  6. package/dist/modules/cpq/api/_helpers/adjustmentCommandRoute.js.map +7 -0
  7. package/dist/modules/cpq/api/_helpers/quoteMutationGuard.js +23 -0
  8. package/dist/modules/cpq/api/_helpers/quoteMutationGuard.js.map +7 -0
  9. package/dist/modules/cpq/api/_helpers/quoteRouteOpenApi.js +19 -0
  10. package/dist/modules/cpq/api/_helpers/quoteRouteOpenApi.js.map +7 -0
  11. package/dist/modules/cpq/api/orders/[orderId]/route.js +17 -1
  12. package/dist/modules/cpq/api/orders/[orderId]/route.js.map +2 -2
  13. package/dist/modules/cpq/api/orders/route.js +47 -2
  14. package/dist/modules/cpq/api/orders/route.js.map +2 -2
  15. package/dist/modules/cpq/api/quotes/[quoteId]/items/[lineId]/restore/route.js +54 -0
  16. package/dist/modules/cpq/api/quotes/[quoteId]/items/[lineId]/restore/route.js.map +7 -0
  17. package/dist/modules/cpq/api/quotes/[quoteId]/items/[lineId]/route.js +42 -2
  18. package/dist/modules/cpq/api/quotes/[quoteId]/items/[lineId]/route.js.map +2 -2
  19. package/dist/modules/cpq/api/quotes/[quoteId]/items/route.js +27 -2
  20. package/dist/modules/cpq/api/quotes/[quoteId]/items/route.js.map +2 -2
  21. package/dist/modules/cpq/api/quotes/[quoteId]/price-adjustments/[adjustmentId]/route.js +47 -0
  22. package/dist/modules/cpq/api/quotes/[quoteId]/price-adjustments/[adjustmentId]/route.js.map +7 -0
  23. package/dist/modules/cpq/api/quotes/[quoteId]/price-adjustments/preview/route.js +30 -0
  24. package/dist/modules/cpq/api/quotes/[quoteId]/price-adjustments/preview/route.js.map +7 -0
  25. package/dist/modules/cpq/api/quotes/[quoteId]/price-adjustments/route.js +47 -0
  26. package/dist/modules/cpq/api/quotes/[quoteId]/price-adjustments/route.js.map +7 -0
  27. package/dist/modules/cpq/api/quotes/[quoteId]/recalculate/route.js +32 -2
  28. package/dist/modules/cpq/api/quotes/[quoteId]/recalculate/route.js.map +2 -2
  29. package/dist/modules/cpq/api/quotes/[quoteId]/status/route.js +33 -2
  30. package/dist/modules/cpq/api/quotes/[quoteId]/status/route.js.map +2 -2
  31. package/dist/modules/cpq/api/quotes/price/route.js +43 -3
  32. package/dist/modules/cpq/api/quotes/price/route.js.map +2 -2
  33. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js +1 -1
  34. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js.map +1 -1
  35. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js +22 -8
  36. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js.map +2 -2
  37. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js +89 -232
  38. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js.map +2 -2
  39. package/dist/modules/cpq/backend/cpq/orders/page.meta.js +1 -1
  40. package/dist/modules/cpq/backend/cpq/orders/page.meta.js.map +1 -1
  41. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js +205 -0
  42. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js.map +7 -0
  43. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentsPanel.js +79 -0
  44. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentsPanel.js.map +7 -0
  45. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/arcLineRemoval.js +53 -0
  46. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/arcLineRemoval.js.map +7 -0
  47. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/priceAdjustmentContext.js +107 -0
  48. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/priceAdjustmentContext.js.map +7 -0
  49. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/usePriceAdjustments.js +130 -0
  50. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/usePriceAdjustments.js.map +7 -0
  51. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js +144 -221
  52. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js.map +3 -3
  53. package/dist/modules/cpq/backend/cpq/quotes/page.meta.js +1 -1
  54. package/dist/modules/cpq/backend/cpq/quotes/page.meta.js.map +1 -1
  55. package/dist/modules/cpq/ce.js +8 -0
  56. package/dist/modules/cpq/ce.js.map +2 -2
  57. package/dist/modules/cpq/cli.js +34 -1
  58. package/dist/modules/cpq/cli.js.map +2 -2
  59. package/dist/modules/cpq/commands/price-adjustments.js +107 -0
  60. package/dist/modules/cpq/commands/price-adjustments.js.map +7 -0
  61. package/dist/modules/cpq/components/ArcLineDiff.js +53 -0
  62. package/dist/modules/cpq/components/ArcLineDiff.js.map +7 -0
  63. package/dist/modules/cpq/components/ChargeBreakdownTable.js +154 -0
  64. package/dist/modules/cpq/components/ChargeBreakdownTable.js.map +7 -0
  65. package/dist/modules/cpq/components/PriceWaterfall.js +66 -0
  66. package/dist/modules/cpq/components/PriceWaterfall.js.map +7 -0
  67. package/dist/modules/cpq/components/PricingSummaryCard.js +117 -0
  68. package/dist/modules/cpq/components/PricingSummaryCard.js.map +7 -0
  69. package/dist/modules/cpq/components/useGrantedFeatures.js +27 -0
  70. package/dist/modules/cpq/components/useGrantedFeatures.js.map +7 -0
  71. package/dist/modules/cpq/data/entities.js +97 -0
  72. package/dist/modules/cpq/data/entities.js.map +2 -2
  73. package/dist/modules/cpq/data/price-adjustments.js +70 -0
  74. package/dist/modules/cpq/data/price-adjustments.js.map +7 -0
  75. package/dist/modules/cpq/data/validators.js +4 -0
  76. package/dist/modules/cpq/data/validators.js.map +2 -2
  77. package/dist/modules/cpq/di.js +6 -0
  78. package/dist/modules/cpq/di.js.map +2 -2
  79. package/dist/modules/cpq/events.js +47 -0
  80. package/dist/modules/cpq/events.js.map +2 -2
  81. package/dist/modules/cpq/index.js +1 -1
  82. package/dist/modules/cpq/index.js.map +2 -2
  83. package/dist/modules/cpq/lib/auditActor.js +10 -0
  84. package/dist/modules/cpq/lib/auditActor.js.map +7 -0
  85. package/dist/modules/cpq/lib/formatMoney.js +7 -0
  86. package/dist/modules/cpq/lib/formatMoney.js.map +7 -0
  87. package/dist/modules/cpq/lib/priceAdjustmentDefaults.js +60 -0
  88. package/dist/modules/cpq/lib/priceAdjustmentDefaults.js.map +7 -0
  89. package/dist/modules/cpq/lib/priceAdjustmentView.js +169 -0
  90. package/dist/modules/cpq/lib/priceAdjustmentView.js.map +7 -0
  91. package/dist/modules/cpq/lib/quotePermissions.js +13 -0
  92. package/dist/modules/cpq/lib/quotePermissions.js.map +7 -0
  93. package/dist/modules/cpq/lib/quoteSummaryView.js +28 -0
  94. package/dist/modules/cpq/lib/quoteSummaryView.js.map +7 -0
  95. package/dist/modules/cpq/migrations/Migration20261110213052.js +22 -0
  96. package/dist/modules/cpq/migrations/Migration20261110213052.js.map +7 -0
  97. package/dist/modules/cpq/services/arcLineRemoval.js +53 -0
  98. package/dist/modules/cpq/services/arcLineRemoval.js.map +7 -0
  99. package/dist/modules/cpq/services/arcPriceFreeze.js +79 -0
  100. package/dist/modules/cpq/services/arcPriceFreeze.js.map +7 -0
  101. package/dist/modules/cpq/services/cpqOrderService.js +25 -28
  102. package/dist/modules/cpq/services/cpqOrderService.js.map +2 -2
  103. package/dist/modules/cpq/services/cpqPricingService.js +7 -0
  104. package/dist/modules/cpq/services/cpqPricingService.js.map +2 -2
  105. package/dist/modules/cpq/services/cpqQuotingService.js +330 -109
  106. package/dist/modules/cpq/services/cpqQuotingService.js.map +2 -2
  107. package/dist/modules/cpq/services/orderPricingSummary.js +26 -0
  108. package/dist/modules/cpq/services/orderPricingSummary.js.map +7 -0
  109. package/dist/modules/cpq/services/priceAdjustments/adjustmentService.js +264 -0
  110. package/dist/modules/cpq/services/priceAdjustments/adjustmentService.js.map +7 -0
  111. package/dist/modules/cpq/services/priceAdjustments/chargeWaterfall.js +25 -0
  112. package/dist/modules/cpq/services/priceAdjustments/chargeWaterfall.js.map +7 -0
  113. package/dist/modules/cpq/services/priceAdjustments/loadQuoteAdjustments.js +38 -0
  114. package/dist/modules/cpq/services/priceAdjustments/loadQuoteAdjustments.js.map +7 -0
  115. package/dist/modules/cpq/services/priceAdjustments/pricingSnapshot.js +104 -0
  116. package/dist/modules/cpq/services/priceAdjustments/pricingSnapshot.js.map +7 -0
  117. package/dist/modules/cpq/services/priceAdjustments/quoteAdjustmentLifecycle.js +102 -0
  118. package/dist/modules/cpq/services/priceAdjustments/quoteAdjustmentLifecycle.js.map +7 -0
  119. package/dist/modules/cpq/services/priceAdjustments/quotePricingEvents.js +52 -0
  120. package/dist/modules/cpq/services/priceAdjustments/quotePricingEvents.js.map +7 -0
  121. package/dist/modules/cpq/services/priceAdjustments/quotePricingWrite.js +37 -0
  122. package/dist/modules/cpq/services/priceAdjustments/quotePricingWrite.js.map +7 -0
  123. package/dist/modules/cpq/services/priceAdjustments/resolveManualAdjustments.js +107 -0
  124. package/dist/modules/cpq/services/priceAdjustments/resolveManualAdjustments.js.map +7 -0
  125. package/dist/modules/cpq/services/priceAdjustments/storedAdjustmentFailure.js +30 -0
  126. package/dist/modules/cpq/services/priceAdjustments/storedAdjustmentFailure.js.map +7 -0
  127. package/dist/modules/cpq/services/types.js.map +2 -2
  128. package/dist/modules/cpq/setup.js +6 -0
  129. package/dist/modules/cpq/setup.js.map +2 -2
  130. package/package.json +1 -1
  131. package/src/modules/cpq/__integration__/TC-CPQ-ARC-012.spec.ts +134 -0
  132. package/src/modules/cpq/acl.ts +1 -0
  133. package/src/modules/cpq/api/__tests__/adjustmentRoutes.test.ts +79 -0
  134. package/src/modules/cpq/api/__tests__/quoteWriteGuards.test.ts +100 -0
  135. package/src/modules/cpq/api/_helpers/__tests__/quoteMutationGuard.test.ts +48 -0
  136. package/src/modules/cpq/api/_helpers/adjustmentCommandRoute.ts +45 -0
  137. package/src/modules/cpq/api/_helpers/quoteMutationGuard.ts +38 -0
  138. package/src/modules/cpq/api/_helpers/quoteRouteOpenApi.ts +19 -0
  139. package/src/modules/cpq/api/orders/[orderId]/route.ts +18 -0
  140. package/src/modules/cpq/api/orders/route.ts +51 -1
  141. package/src/modules/cpq/api/quotes/[quoteId]/items/[lineId]/restore/route.ts +56 -0
  142. package/src/modules/cpq/api/quotes/[quoteId]/items/[lineId]/route.ts +48 -1
  143. package/src/modules/cpq/api/quotes/[quoteId]/items/route.ts +31 -1
  144. package/src/modules/cpq/api/quotes/[quoteId]/price-adjustments/[adjustmentId]/route.ts +39 -0
  145. package/src/modules/cpq/api/quotes/[quoteId]/price-adjustments/preview/route.ts +24 -0
  146. package/src/modules/cpq/api/quotes/[quoteId]/price-adjustments/route.ts +40 -0
  147. package/src/modules/cpq/api/quotes/[quoteId]/recalculate/__tests__/route.test.ts +95 -0
  148. package/src/modules/cpq/api/quotes/[quoteId]/recalculate/route.ts +40 -1
  149. package/src/modules/cpq/api/quotes/[quoteId]/status/__tests__/route.test.ts +74 -0
  150. package/src/modules/cpq/api/quotes/[quoteId]/status/route.ts +37 -1
  151. package/src/modules/cpq/api/quotes/price/__tests__/route.test.ts +37 -0
  152. package/src/modules/cpq/api/quotes/price/route.ts +28 -2
  153. package/src/modules/cpq/backend/cpq/inventory/page.meta.ts +1 -1
  154. package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.tsx +32 -10
  155. package/src/modules/cpq/backend/cpq/orders/[id]/page.tsx +60 -269
  156. package/src/modules/cpq/backend/cpq/orders/page.meta.ts +1 -1
  157. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.tsx +260 -0
  158. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentsPanel.tsx +124 -0
  159. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/__tests__/PriceAdjustmentsPanel.test.tsx +76 -0
  160. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/arcLineRemoval.tsx +76 -0
  161. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/priceAdjustmentContext.tsx +133 -0
  162. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/usePriceAdjustments.tsx +165 -0
  163. package/src/modules/cpq/backend/cpq/quotes/[id]/page.tsx +174 -263
  164. package/src/modules/cpq/backend/cpq/quotes/page.meta.ts +1 -1
  165. package/src/modules/cpq/ce.ts +8 -0
  166. package/src/modules/cpq/cli.ts +48 -1
  167. package/src/modules/cpq/commands/__tests__/price-adjustments.test.ts +54 -0
  168. package/src/modules/cpq/commands/price-adjustments.ts +90 -0
  169. package/src/modules/cpq/components/ArcLineDiff.tsx +87 -0
  170. package/src/modules/cpq/components/ChargeBreakdownTable.tsx +201 -0
  171. package/src/modules/cpq/components/PriceWaterfall.tsx +94 -0
  172. package/src/modules/cpq/components/PricingSummaryCard.tsx +128 -0
  173. package/src/modules/cpq/components/__tests__/PriceWaterfall.test.tsx +38 -0
  174. package/src/modules/cpq/components/useGrantedFeatures.ts +35 -0
  175. package/src/modules/cpq/data/__tests__/price-adjustment-migration.test.ts +11 -0
  176. package/src/modules/cpq/data/__tests__/price-adjustments.test.ts +26 -0
  177. package/src/modules/cpq/data/entities.ts +83 -0
  178. package/src/modules/cpq/data/price-adjustments.ts +67 -0
  179. package/src/modules/cpq/data/validators.ts +3 -0
  180. package/src/modules/cpq/di.ts +6 -0
  181. package/src/modules/cpq/events.ts +53 -2
  182. package/src/modules/cpq/index.ts +1 -1
  183. package/src/modules/cpq/lib/__tests__/auditActor.test.ts +12 -0
  184. package/src/modules/cpq/lib/__tests__/priceAdjustmentDefaults.test.ts +37 -0
  185. package/src/modules/cpq/lib/__tests__/priceAdjustmentView.test.ts +152 -0
  186. package/src/modules/cpq/lib/__tests__/quotePermissions.test.ts +30 -0
  187. package/src/modules/cpq/lib/__tests__/quoteSummaryView.test.ts +56 -0
  188. package/src/modules/cpq/lib/auditActor.ts +13 -0
  189. package/src/modules/cpq/lib/formatMoney.ts +4 -0
  190. package/src/modules/cpq/lib/priceAdjustmentDefaults.ts +36 -0
  191. package/src/modules/cpq/lib/priceAdjustmentView.ts +259 -0
  192. package/src/modules/cpq/lib/quotePermissions.ts +22 -0
  193. package/src/modules/cpq/lib/quoteSummaryView.ts +51 -0
  194. package/src/modules/cpq/migrations/.snapshot-open-mercato.json +3298 -2423
  195. package/src/modules/cpq/migrations/Migration20261110213052.ts +22 -0
  196. package/src/modules/cpq/services/__tests__/_helpers/mockEm.ts +9 -2
  197. package/src/modules/cpq/services/__tests__/adjustmentService.test.ts +183 -0
  198. package/src/modules/cpq/services/__tests__/arcLineRemoval.test.ts +109 -0
  199. package/src/modules/cpq/services/__tests__/arcPriceFreeze.test.ts +141 -0
  200. package/src/modules/cpq/services/__tests__/chargeWaterfall.test.ts +28 -0
  201. package/src/modules/cpq/services/__tests__/cpqOrderService.test.ts +35 -2
  202. package/src/modules/cpq/services/__tests__/cpqPricingService.test.ts +57 -0
  203. package/src/modules/cpq/services/__tests__/cpqQuotingService.arc.test.ts +237 -0
  204. package/src/modules/cpq/services/__tests__/cpqQuotingService.test.ts +58 -3
  205. package/src/modules/cpq/services/__tests__/orderPricingSummary.test.ts +50 -0
  206. package/src/modules/cpq/services/__tests__/pricingSnapshot.test.ts +62 -0
  207. package/src/modules/cpq/services/__tests__/quoteAdjustmentLifecycle.test.ts +35 -0
  208. package/src/modules/cpq/services/__tests__/quoteAdjustmentPricing.test.ts +65 -0
  209. package/src/modules/cpq/services/__tests__/quoteCloneAdjustments.test.ts +45 -0
  210. package/src/modules/cpq/services/__tests__/quoteDetachTargetAdjustments.test.ts +54 -0
  211. package/src/modules/cpq/services/__tests__/quoteEventsService.test.ts +72 -0
  212. package/src/modules/cpq/services/__tests__/quotePricingEvents.test.ts +126 -0
  213. package/src/modules/cpq/services/__tests__/quotePricingIsolation.test.ts +52 -0
  214. package/src/modules/cpq/services/__tests__/quotePricingWrite.test.ts +74 -0
  215. package/src/modules/cpq/services/__tests__/resolveManualAdjustments.test.ts +90 -0
  216. package/src/modules/cpq/services/__tests__/storedAdjustmentFailure.test.ts +9 -0
  217. package/src/modules/cpq/services/arcLineRemoval.ts +87 -0
  218. package/src/modules/cpq/services/arcPriceFreeze.ts +165 -0
  219. package/src/modules/cpq/services/cpqOrderService.ts +22 -28
  220. package/src/modules/cpq/services/cpqPricingService.ts +8 -0
  221. package/src/modules/cpq/services/cpqQuotingService.ts +374 -125
  222. package/src/modules/cpq/services/orderPricingSummary.ts +47 -0
  223. package/src/modules/cpq/services/priceAdjustments/adjustmentService.ts +249 -0
  224. package/src/modules/cpq/services/priceAdjustments/chargeWaterfall.ts +28 -0
  225. package/src/modules/cpq/services/priceAdjustments/loadQuoteAdjustments.ts +25 -0
  226. package/src/modules/cpq/services/priceAdjustments/pricingSnapshot.ts +86 -0
  227. package/src/modules/cpq/services/priceAdjustments/quoteAdjustmentLifecycle.ts +68 -0
  228. package/src/modules/cpq/services/priceAdjustments/quotePricingEvents.ts +94 -0
  229. package/src/modules/cpq/services/priceAdjustments/quotePricingWrite.ts +51 -0
  230. package/src/modules/cpq/services/priceAdjustments/resolveManualAdjustments.ts +116 -0
  231. package/src/modules/cpq/services/priceAdjustments/storedAdjustmentFailure.ts +31 -0
  232. package/src/modules/cpq/services/types.ts +34 -1
  233. package/src/modules/cpq/setup.ts +7 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/cpq/components/PriceWaterfall.tsx"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport {\n discountDepth,\n formatDepth,\n waterfallRows,\n type WaterfallChargeInput,\n} from '../lib/priceAdjustmentView'\n\nfunction money(amount: number, currency: string): string {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount)\n}\n\nconst TYPE_FALLBACKS: Record<string, string> = {\n discount_percent: '% discount',\n discount_absolute: 'amount off',\n surcharge_percent: '% surcharge',\n surcharge_absolute: 'fixed surcharge',\n price_override: 'price override',\n}\n\n/** Signed depth badge: \"\u221220%\" for a discount, \"+5%\" for a surcharge; text, never colour only. */\nexport function DepthBadge({ before, after, title }: { before: number | null | undefined; after: number | null | undefined; title?: string }) {\n const label = formatDepth(discountDepth(before, after))\n if (!label) return null\n return <Tag variant=\"neutral\" className=\"px-1.5 text-xs font-mono\" title={title}>{label}</Tag>\n}\n\nexport type PriceWaterfallProps = {\n charge: WaterfallChargeInput & { chargeName?: string }\n currency: string\n /** Reason code \u2192 label; manual rows fall back to the code. */\n reasonLabels?: Record<string, string>\n /** Optional per-adjustment actions (edit / delete) rendered on manual rows. */\n renderManualActions?: (adjustmentId: string) => React.ReactNode\n}\n\n/** Read-only list \u2192 rule \u2192 standard \u2192 manual \u2192 offer breakdown for one charge (unit prices). */\nexport function PriceWaterfall({ charge, currency, reasonLabels, renderManualActions }: PriceWaterfallProps) {\n const t = useT()\n const rows = waterfallRows(charge)\n const fmtValue = (ruleType: string, value: number) =>\n ruleType.endsWith('_percent') ? `${value}%` : money(value, currency)\n return (\n <table className=\"w-full text-xs\" data-testid=\"cpq-price-waterfall\">\n <thead>\n <tr className=\"text-muted-foreground\">\n <th className=\"text-left py-0.5 font-medium\">{t('cpq.priceAdjustments.waterfall.step', 'Step')}</th>\n <th className=\"text-left py-0.5 font-medium\">{t('cpq.priceAdjustments.waterfall.source', 'Source')}</th>\n <th className=\"text-right py-0.5 font-medium\">{t('cpq.priceAdjustments.waterfall.value', 'Value')}</th>\n <th className=\"text-right py-0.5 font-medium\">{t('cpq.priceAdjustments.waterfall.delta', 'Delta')}</th>\n <th className=\"text-right py-0.5 font-medium\">{t('cpq.priceAdjustments.waterfall.unitPrice', 'Unit price')}</th>\n {renderManualActions && <th className=\"w-16\" />}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, index) => {\n if (row.kind === 'list' || row.kind === 'standard' || row.kind === 'offer') {\n const label = row.kind === 'list'\n ? t('cpq.priceAdjustments.waterfall.list', 'List price')\n : row.kind === 'standard'\n ? t('cpq.priceAdjustments.waterfall.standard', 'Standard price')\n : t('cpq.priceAdjustments.waterfall.offer', 'Offer price')\n return (\n <tr key={`${row.kind}-${index}`} className={`border-t border-border/30 ${row.kind === 'offer' ? 'font-semibold' : 'font-medium'}`}>\n <td className=\"py-0.5\" colSpan={4}>{label}</td>\n <td className=\"py-0.5 text-right font-mono\">{money(row.unitPrice, currency)}</td>\n {renderManualActions && <td />}\n </tr>\n )\n }\n const source = row.kind === 'rule'\n ? `${t('cpq.priceAdjustments.waterfall.rule', 'Price rule')}: ${row.label}`\n : `${t('cpq.priceAdjustments.waterfall.manual', 'Negotiated')}: ${reasonLabels?.[row.reasonCode ?? ''] ?? row.reasonCode ?? row.label}`\n return (\n <tr key={`${row.kind}-${index}`} className=\"border-t border-border/30\">\n <td className=\"py-0.5 pl-3 text-muted-foreground\">{t(`cpq.priceAdjustments.types.${row.ruleType}`, TYPE_FALLBACKS[row.ruleType] ?? row.ruleType)}</td>\n <td className=\"py-0.5\">{source}</td>\n <td className=\"py-0.5 text-right font-mono\">{fmtValue(row.ruleType, row.value)}</td>\n <td className=\"py-0.5 text-right font-mono\">{row.delta > 0 ? '+' : ''}{money(row.delta, currency)}</td>\n <td className=\"py-0.5 text-right font-mono\">{money(row.unitPriceAfter, currency)}</td>\n {renderManualActions && (\n <td className=\"py-0.5 text-right\">{row.kind === 'manual' && row.adjustmentId ? renderManualActions(row.adjustmentId) : null}</td>\n )}\n </tr>\n )\n })}\n </tbody>\n </table>\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,117 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
4
+ import { formatDepth } from "../lib/priceAdjustmentView.js";
5
+ import { chargeTypeDepths, formatChangePct } from "../lib/quoteSummaryView.js";
6
+ import { formatMoney } from "../lib/formatMoney.js";
7
+ function SummaryFigure({
8
+ label,
9
+ value,
10
+ note,
11
+ title,
12
+ size = "lg",
13
+ valueClassName,
14
+ testId
15
+ }) {
16
+ return /* @__PURE__ */ jsxs("div", { "data-testid": testId, children: [
17
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", title, children: label }),
18
+ /* @__PURE__ */ jsxs("p", { className: `${size === "lg" ? "text-lg" : "text-sm"} font-semibold font-mono ${valueClassName ?? ""}`, children: [
19
+ value,
20
+ note && /* @__PURE__ */ jsxs("span", { className: "ml-1.5 text-xs font-normal text-muted-foreground", children: [
21
+ "(",
22
+ note,
23
+ ")"
24
+ ] })
25
+ ] })
26
+ ] });
27
+ }
28
+ function PricingSummaryCard({ summary, currency, arcDelta }) {
29
+ const t = useT();
30
+ const typeDepths = chargeTypeDepths(summary);
31
+ const usageCharges = summary.usageCharges ?? [];
32
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4", "data-testid": "cpq-pricing-summary", children: [
33
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium mb-3", children: t("cpq.quotes.summary.title", "Pricing Summary") }),
34
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-4", children: [
35
+ /* @__PURE__ */ jsx(
36
+ SummaryFigure,
37
+ {
38
+ label: t("cpq.quotes.summary.nrc", "Non-Recurring (NRC)"),
39
+ value: formatMoney(summary.nrcTotal, currency),
40
+ note: formatDepth(typeDepths.nrc),
41
+ testId: "cpq-summary-nrc"
42
+ }
43
+ ),
44
+ /* @__PURE__ */ jsx(
45
+ SummaryFigure,
46
+ {
47
+ label: t("cpq.quotes.summary.mrc", "Monthly Recurring (MRC)"),
48
+ value: formatMoney(summary.mrcTotal, currency),
49
+ note: formatDepth(typeDepths.mrc),
50
+ testId: "cpq-summary-mrc"
51
+ }
52
+ ),
53
+ summary.dealValue && /* @__PURE__ */ jsx(
54
+ SummaryFigure,
55
+ {
56
+ label: t("cpq.priceAdjustments.summary.dealValue", "Deal value"),
57
+ title: t("cpq.priceAdjustments.summary.hint", "Deal value counts recurring charges over the term plus one-time charges; existing subscription items on change quotes are excluded."),
58
+ value: formatMoney(summary.dealValue.offer, currency),
59
+ note: formatDepth(summary.discountDepth?.total ?? null),
60
+ testId: "cpq-deal-value"
61
+ }
62
+ ),
63
+ summary.usageTotalEstimated != null && /* @__PURE__ */ jsx(
64
+ SummaryFigure,
65
+ {
66
+ label: t("cpq.quotes.summary.usageEstimated", "Usage (est.)"),
67
+ value: formatMoney(summary.usageTotalEstimated, currency)
68
+ }
69
+ ),
70
+ usageCharges.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
71
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("cpq.quotes.summary.usageCharges", "Usage Charges") }),
72
+ usageCharges.map((uc, i) => /* @__PURE__ */ jsxs("p", { className: "text-xs mt-0.5", children: [
73
+ uc.chargeName,
74
+ ": ",
75
+ formatMoney(uc.unitPrice, currency),
76
+ "/unit"
77
+ ] }, i))
78
+ ] })
79
+ ] }),
80
+ arcDelta && /* @__PURE__ */ jsxs("div", { className: "mt-4 grid grid-cols-2 sm:grid-cols-4 gap-4 border-t pt-3", "data-testid": "cpq-arc-delta", children: [
81
+ /* @__PURE__ */ jsx(
82
+ SummaryFigure,
83
+ {
84
+ size: "sm",
85
+ testId: "cpq-arc-current-mrc",
86
+ label: t("cpq.quotes.summary.arc.currentMrc", "Current MRC"),
87
+ value: formatMoney(arcDelta.currentMrc, currency)
88
+ }
89
+ ),
90
+ /* @__PURE__ */ jsx(
91
+ SummaryFigure,
92
+ {
93
+ size: "sm",
94
+ testId: "cpq-arc-new-mrc",
95
+ label: t("cpq.quotes.summary.arc.newMrc", "New MRC"),
96
+ value: formatMoney(arcDelta.newMrc, currency)
97
+ }
98
+ ),
99
+ /* @__PURE__ */ jsx(
100
+ SummaryFigure,
101
+ {
102
+ size: "sm",
103
+ testId: "cpq-arc-mrc-change",
104
+ label: t("cpq.quotes.summary.arc.mrcChange", "MRC change"),
105
+ value: `${arcDelta.delta > 0 ? "+" : ""}${formatMoney(arcDelta.delta, currency)}`,
106
+ valueClassName: arcDelta.delta > 0 ? "text-status-success-text" : arcDelta.delta < 0 ? "text-destructive" : void 0,
107
+ note: formatChangePct(arcDelta.deltaPct)
108
+ }
109
+ )
110
+ ] })
111
+ ] });
112
+ }
113
+ export {
114
+ PricingSummaryCard,
115
+ SummaryFigure
116
+ };
117
+ //# sourceMappingURL=PricingSummaryCard.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/cpq/components/PricingSummaryCard.tsx"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { formatDepth } from '../lib/priceAdjustmentView'\nimport { chargeTypeDepths, formatChangePct, type ArcRecurringDelta } from '../lib/quoteSummaryView'\nimport { formatMoney } from '../lib/formatMoney'\n\n/** Pricing summary fields shared by quote and order results. Waterfall fields are absent on legacy snapshots. */\nexport type PricingSummaryView = {\n nrcTotal: number\n mrcTotal: number\n listNrcTotal?: number\n listMrcTotal?: number\n dealValue?: { list: number; standard: number; offer: number }\n discountDepth?: { total: number | null } | null\n usageTotalEstimated?: number | null\n usageCharges?: Array<{ chargeName: string; unitPrice: number }>\n}\n\nexport function SummaryFigure({\n label,\n value,\n note,\n title,\n size = 'lg',\n valueClassName,\n testId,\n}: {\n label: string\n value: string\n note?: string | null\n title?: string\n size?: 'lg' | 'sm'\n valueClassName?: string\n testId?: string\n}) {\n return (\n <div data-testid={testId}>\n <p className=\"text-xs text-muted-foreground\" title={title}>{label}</p>\n <p className={`${size === 'lg' ? 'text-lg' : 'text-sm'} font-semibold font-mono ${valueClassName ?? ''}`}>\n {value}\n {note && <span className=\"ml-1.5 text-xs font-normal text-muted-foreground\">({note})</span>}\n </p>\n </div>\n )\n}\n\n/**\n * NRC / MRC / deal value with discount depth in brackets, plus the ARC\n * current \u2192 new MRC row on Amend / Renew documents. Shared by the quote and\n * order detail pages so both read the same.\n */\nexport function PricingSummaryCard({ summary, currency, arcDelta }: {\n summary: PricingSummaryView\n currency: string\n arcDelta?: ArcRecurringDelta | null\n}) {\n const t = useT()\n const typeDepths = chargeTypeDepths(summary)\n const usageCharges = summary.usageCharges ?? []\n return (\n <div className=\"rounded-lg border bg-card p-4\" data-testid=\"cpq-pricing-summary\">\n <h3 className=\"text-sm font-medium mb-3\">{t('cpq.quotes.summary.title', 'Pricing Summary')}</h3>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n <SummaryFigure\n label={t('cpq.quotes.summary.nrc', 'Non-Recurring (NRC)')}\n value={formatMoney(summary.nrcTotal, currency)}\n note={formatDepth(typeDepths.nrc)}\n testId=\"cpq-summary-nrc\"\n />\n <SummaryFigure\n label={t('cpq.quotes.summary.mrc', 'Monthly Recurring (MRC)')}\n value={formatMoney(summary.mrcTotal, currency)}\n note={formatDepth(typeDepths.mrc)}\n testId=\"cpq-summary-mrc\"\n />\n {summary.dealValue && (\n <SummaryFigure\n label={t('cpq.priceAdjustments.summary.dealValue', 'Deal value')}\n title={t('cpq.priceAdjustments.summary.hint', 'Deal value counts recurring charges over the term plus one-time charges; existing subscription items on change quotes are excluded.')}\n value={formatMoney(summary.dealValue.offer, currency)}\n note={formatDepth(summary.discountDepth?.total ?? null)}\n testId=\"cpq-deal-value\"\n />\n )}\n {summary.usageTotalEstimated != null && (\n <SummaryFigure\n label={t('cpq.quotes.summary.usageEstimated', 'Usage (est.)')}\n value={formatMoney(summary.usageTotalEstimated, currency)}\n />\n )}\n {usageCharges.length > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground\">{t('cpq.quotes.summary.usageCharges', 'Usage Charges')}</p>\n {usageCharges.map((uc, i) => (\n <p key={i} className=\"text-xs mt-0.5\">{uc.chargeName}: {formatMoney(uc.unitPrice, currency)}/unit</p>\n ))}\n </div>\n )}\n </div>\n {arcDelta && (\n <div className=\"mt-4 grid grid-cols-2 sm:grid-cols-4 gap-4 border-t pt-3\" data-testid=\"cpq-arc-delta\">\n <SummaryFigure\n size=\"sm\"\n testId=\"cpq-arc-current-mrc\"\n label={t('cpq.quotes.summary.arc.currentMrc', 'Current MRC')}\n value={formatMoney(arcDelta.currentMrc, currency)}\n />\n <SummaryFigure\n size=\"sm\"\n testId=\"cpq-arc-new-mrc\"\n label={t('cpq.quotes.summary.arc.newMrc', 'New MRC')}\n value={formatMoney(arcDelta.newMrc, currency)}\n />\n <SummaryFigure\n size=\"sm\"\n testId=\"cpq-arc-mrc-change\"\n label={t('cpq.quotes.summary.arc.mrcChange', 'MRC change')}\n value={`${arcDelta.delta > 0 ? '+' : ''}${formatMoney(arcDelta.delta, currency)}`}\n valueClassName={arcDelta.delta > 0 ? 'text-status-success-text' : arcDelta.delta < 0 ? 'text-destructive' : undefined}\n note={formatChangePct(arcDelta.deltaPct)}\n />\n </div>\n )}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
4
+ function useGrantedFeatures(features) {
5
+ const [granted, setGranted] = React.useState([]);
6
+ const key = features.join("|");
7
+ React.useEffect(() => {
8
+ if (!key) return;
9
+ let cancelled = false;
10
+ void (async () => {
11
+ const call = await apiCall("/api/auth/feature-check", {
12
+ method: "POST",
13
+ headers: { "content-type": "application/json" },
14
+ body: JSON.stringify({ features: key.split("|") })
15
+ });
16
+ if (!cancelled && call.ok && call.result?.granted) setGranted(call.result.granted);
17
+ })();
18
+ return () => {
19
+ cancelled = true;
20
+ };
21
+ }, [key]);
22
+ return granted;
23
+ }
24
+ export {
25
+ useGrantedFeatures
26
+ };
27
+ //# sourceMappingURL=useGrantedFeatures.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/cpq/components/useGrantedFeatures.ts"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\n\ntype FeatureCheckResponse = { granted: string[] }\n\n/**\n * Resolve which of `features` the current user holds, through the framework's\n * `POST /api/auth/feature-check` endpoint (the same one the component-override\n * provider uses). Returns an empty list until the check completes, so callers\n * hide privileged actions by default.\n */\nexport function useGrantedFeatures(features: readonly string[]): readonly string[] {\n const [granted, setGranted] = React.useState<readonly string[]>([])\n const key = features.join('|')\n\n React.useEffect(() => {\n if (!key) return\n let cancelled = false\n void (async () => {\n const call = await apiCall<FeatureCheckResponse>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: key.split('|') }),\n })\n if (!cancelled && call.ok && call.result?.granted) setGranted(call.result.granted)\n })()\n return () => {\n cancelled = true\n }\n }, [key])\n\n return granted\n}\n"],
5
+ "mappings": ";AAEA,YAAY,WAAW;AACvB,SAAS,eAAe;AAUjB,SAAS,mBAAmB,UAAgD;AACjF,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAA4B,CAAC,CAAC;AAClE,QAAM,MAAM,SAAS,KAAK,GAAG;AAE7B,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,IAAK;AACV,QAAI,YAAY;AAChB,UAAM,YAAY;AAChB,YAAM,OAAO,MAAM,QAA8B,2BAA2B;AAAA,QAC1E,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,UAAU,IAAI,MAAM,GAAG,EAAE,CAAC;AAAA,MACnD,CAAC;AACD,UAAI,CAAC,aAAa,KAAK,MAAM,KAAK,QAAQ,QAAS,YAAW,KAAK,OAAO,OAAO;AAAA,IACnF,GAAG;AACH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AAER,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -678,6 +678,7 @@ CpqPriceRule = __decorateClass([
678
678
  OptionalProps;
679
679
  let CpqQuoteConfiguration = class {
680
680
  constructor() {
681
+ this.pricingRevision = 0;
681
682
  this.cpqStatus = "new";
682
683
  this.version = 1;
683
684
  this.currencyCode = "USD";
@@ -701,6 +702,9 @@ __decorateClass([
701
702
  __decorateClass([
702
703
  Property({ name: "customer_id", type: "uuid" })
703
704
  ], CpqQuoteConfiguration.prototype, "customerId", 2);
705
+ __decorateClass([
706
+ Property({ name: "pricing_revision", type: "integer", default: 0 })
707
+ ], CpqQuoteConfiguration.prototype, "pricingRevision", 2);
704
708
  __decorateClass([
705
709
  Property({ name: "cpq_status", type: "text", default: "new" })
706
710
  ], CpqQuoteConfiguration.prototype, "cpqStatus", 2);
@@ -1534,6 +1538,98 @@ CpqSubscriptionChangeLog = __decorateClass([
1534
1538
  properties: ["sourceOrderId", "subscriptionId"]
1535
1539
  })
1536
1540
  ], CpqSubscriptionChangeLog);
1541
+ OptionalProps;
1542
+ let CpqQuotePriceAdjustment = class {
1543
+ constructor() {
1544
+ this.chargeCode = null;
1545
+ this.chargeTypeFilter = null;
1546
+ this.currencyCode = null;
1547
+ this.windowKind = "relative";
1548
+ this.fromMonth = 1;
1549
+ this.toMonth = null;
1550
+ this.reasonNote = null;
1551
+ this.updatedByUserId = null;
1552
+ this.isActive = true;
1553
+ this.createdAt = /* @__PURE__ */ new Date();
1554
+ this.updatedAt = /* @__PURE__ */ new Date();
1555
+ this.deletedAt = null;
1556
+ }
1557
+ };
1558
+ __decorateClass([
1559
+ PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
1560
+ ], CpqQuotePriceAdjustment.prototype, "id", 2);
1561
+ __decorateClass([
1562
+ Property({ name: "organization_id", type: "uuid" })
1563
+ ], CpqQuotePriceAdjustment.prototype, "organizationId", 2);
1564
+ __decorateClass([
1565
+ Property({ name: "tenant_id", type: "uuid" })
1566
+ ], CpqQuotePriceAdjustment.prototype, "tenantId", 2);
1567
+ __decorateClass([
1568
+ Property({ name: "quote_configuration_id", type: "uuid" })
1569
+ ], CpqQuotePriceAdjustment.prototype, "quoteConfigurationId", 2);
1570
+ __decorateClass([
1571
+ Property({ name: "quote_id", type: "uuid" })
1572
+ ], CpqQuotePriceAdjustment.prototype, "quoteId", 2);
1573
+ __decorateClass([
1574
+ Property({ name: "quote_line_id", type: "uuid" })
1575
+ ], CpqQuotePriceAdjustment.prototype, "quoteLineId", 2);
1576
+ __decorateClass([
1577
+ Property({ type: "text" })
1578
+ ], CpqQuotePriceAdjustment.prototype, "level", 2);
1579
+ __decorateClass([
1580
+ Property({ name: "charge_code", type: "text", nullable: true })
1581
+ ], CpqQuotePriceAdjustment.prototype, "chargeCode", 2);
1582
+ __decorateClass([
1583
+ Property({ name: "charge_type_filter", type: "text", nullable: true })
1584
+ ], CpqQuotePriceAdjustment.prototype, "chargeTypeFilter", 2);
1585
+ __decorateClass([
1586
+ Property({ name: "adjustment_type", type: "text" })
1587
+ ], CpqQuotePriceAdjustment.prototype, "adjustmentType", 2);
1588
+ __decorateClass([
1589
+ Property({ type: "numeric", columnType: "numeric(18, 4)" })
1590
+ ], CpqQuotePriceAdjustment.prototype, "value", 2);
1591
+ __decorateClass([
1592
+ Property({ name: "currency_code", type: "text", nullable: true })
1593
+ ], CpqQuotePriceAdjustment.prototype, "currencyCode", 2);
1594
+ __decorateClass([
1595
+ Property({ name: "window_kind", type: "text", default: "relative" })
1596
+ ], CpqQuotePriceAdjustment.prototype, "windowKind", 2);
1597
+ __decorateClass([
1598
+ Property({ name: "from_month", type: "integer", default: 1 })
1599
+ ], CpqQuotePriceAdjustment.prototype, "fromMonth", 2);
1600
+ __decorateClass([
1601
+ Property({ name: "to_month", type: "integer", nullable: true })
1602
+ ], CpqQuotePriceAdjustment.prototype, "toMonth", 2);
1603
+ __decorateClass([
1604
+ Property({ name: "reason_code", type: "text" })
1605
+ ], CpqQuotePriceAdjustment.prototype, "reasonCode", 2);
1606
+ __decorateClass([
1607
+ Property({ name: "reason_note", type: "text", nullable: true })
1608
+ ], CpqQuotePriceAdjustment.prototype, "reasonNote", 2);
1609
+ __decorateClass([
1610
+ Property({ name: "created_by_user_id", type: "uuid" })
1611
+ ], CpqQuotePriceAdjustment.prototype, "createdByUserId", 2);
1612
+ __decorateClass([
1613
+ Property({ name: "updated_by_user_id", type: "uuid", nullable: true })
1614
+ ], CpqQuotePriceAdjustment.prototype, "updatedByUserId", 2);
1615
+ __decorateClass([
1616
+ Property({ name: "is_active", type: "boolean", default: true })
1617
+ ], CpqQuotePriceAdjustment.prototype, "isActive", 2);
1618
+ __decorateClass([
1619
+ Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
1620
+ ], CpqQuotePriceAdjustment.prototype, "createdAt", 2);
1621
+ __decorateClass([
1622
+ Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date() })
1623
+ ], CpqQuotePriceAdjustment.prototype, "updatedAt", 2);
1624
+ __decorateClass([
1625
+ Property({ name: "deleted_at", type: Date, nullable: true })
1626
+ ], CpqQuotePriceAdjustment.prototype, "deletedAt", 2);
1627
+ CpqQuotePriceAdjustment = __decorateClass([
1628
+ Entity({ tableName: "cpq_quote_price_adjustments" }),
1629
+ Index({ name: "cpq_qpa_quote_config_idx", properties: ["organizationId", "tenantId", "quoteConfigurationId"] }),
1630
+ Index({ name: "cpq_qpa_quote_line_idx", properties: ["organizationId", "tenantId", "quoteLineId"] }),
1631
+ Index({ name: "cpq_qpa_quote_idx", properties: ["organizationId", "tenantId", "quoteId"] })
1632
+ ], CpqQuotePriceAdjustment);
1537
1633
  export {
1538
1634
  CpqBundleSlot,
1539
1635
  CpqInventoryAsset,
@@ -1552,6 +1648,7 @@ export {
1552
1648
  CpqProductSpecification,
1553
1649
  CpqQuoteConfiguration,
1554
1650
  CpqQuoteLineConfiguration,
1651
+ CpqQuotePriceAdjustment,
1555
1652
  CpqQuoteTargetSubscription,
1556
1653
  CpqSubscriptionChangeLog,
1557
1654
  CpqWizardDefinition