@powerhousedao/service-offering 1.0.0-dev.4 → 1.0.0-dev.5

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 (235) hide show
  1. package/dist/document-models/facet/v1/actions.d.ts +3 -1
  2. package/dist/document-models/facet/v1/actions.d.ts.map +1 -1
  3. package/dist/document-models/facet/v1/gen/controller.d.ts +4 -0
  4. package/dist/document-models/facet/v1/gen/controller.d.ts.map +1 -0
  5. package/dist/document-models/facet/v1/gen/controller.js +3 -0
  6. package/dist/document-models/facet/v1/gen/document-model.d.ts.map +1 -1
  7. package/dist/document-models/facet/v1/gen/document-model.js +31 -7
  8. package/dist/document-models/facet/v1/gen/document-schema.d.ts +6 -6
  9. package/dist/document-models/facet/v1/gen/index.d.ts +1 -0
  10. package/dist/document-models/facet/v1/gen/index.d.ts.map +1 -1
  11. package/dist/document-models/facet/v1/gen/index.js +1 -0
  12. package/dist/document-models/facet/v1/gen/option-management/error.d.ts +27 -1
  13. package/dist/document-models/facet/v1/gen/option-management/error.d.ts.map +1 -1
  14. package/dist/document-models/facet/v1/gen/option-management/error.js +23 -1
  15. package/dist/document-models/facet/v1/gen/ph-factories.js +2 -2
  16. package/dist/document-models/facet/v1/gen/schema/types.d.ts +2 -2
  17. package/dist/document-models/facet/v1/gen/schema/types.d.ts.map +1 -1
  18. package/dist/document-models/facet/v1/gen/schema/zod.js +2 -2
  19. package/dist/document-models/facet/v1/gen/utils.js +2 -2
  20. package/dist/document-models/facet/v1/module.d.ts +1 -1
  21. package/dist/document-models/facet/v1/module.d.ts.map +1 -1
  22. package/dist/document-models/facet/v1/module.js +4 -1
  23. package/dist/document-models/resource-instance/v1/actions.d.ts +4 -1
  24. package/dist/document-models/resource-instance/v1/actions.d.ts.map +1 -1
  25. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts +34 -1
  26. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts.map +1 -1
  27. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.js +32 -1
  28. package/dist/document-models/resource-instance/v1/gen/controller.d.ts +4 -0
  29. package/dist/document-models/resource-instance/v1/gen/controller.d.ts.map +1 -0
  30. package/dist/document-models/resource-instance/v1/gen/controller.js +3 -0
  31. package/dist/document-models/resource-instance/v1/gen/document-model.d.ts.map +1 -1
  32. package/dist/document-models/resource-instance/v1/gen/document-model.js +222 -70
  33. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts +0 -6
  34. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts.map +1 -1
  35. package/dist/document-models/resource-instance/v1/gen/index.d.ts +1 -0
  36. package/dist/document-models/resource-instance/v1/gen/index.d.ts.map +1 -1
  37. package/dist/document-models/resource-instance/v1/gen/index.js +1 -0
  38. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts +6 -2
  39. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts.map +1 -1
  40. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts +3 -2
  41. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts.map +1 -1
  42. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.js +2 -1
  43. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts +98 -1
  44. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts.map +1 -1
  45. package/dist/document-models/resource-instance/v1/gen/instance-management/error.js +112 -1
  46. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts +2 -1
  47. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts.map +1 -1
  48. package/dist/document-models/resource-instance/v1/gen/ph-factories.d.ts.map +1 -1
  49. package/dist/document-models/resource-instance/v1/gen/ph-factories.js +0 -2
  50. package/dist/document-models/resource-instance/v1/gen/reducer.d.ts.map +1 -1
  51. package/dist/document-models/resource-instance/v1/gen/reducer.js +6 -1
  52. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts +3 -3
  53. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts.map +1 -1
  54. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts +2 -1
  55. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts.map +1 -1
  56. package/dist/document-models/resource-instance/v1/gen/schema/zod.js +5 -3
  57. package/dist/document-models/resource-instance/v1/gen/utils.d.ts.map +1 -1
  58. package/dist/document-models/resource-instance/v1/gen/utils.js +0 -2
  59. package/dist/document-models/resource-instance/v1/module.d.ts +1 -1
  60. package/dist/document-models/resource-instance/v1/module.d.ts.map +1 -1
  61. package/dist/document-models/resource-instance/v1/module.js +4 -1
  62. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.d.ts.map +1 -1
  63. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.js +57 -53
  64. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.d.ts.map +1 -1
  65. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.js +57 -21
  66. package/dist/document-models/resource-instance/v1/tests/instance-management.test.js +11 -1
  67. package/dist/document-models/resource-template/v1/actions.d.ts +3 -1
  68. package/dist/document-models/resource-template/v1/actions.d.ts.map +1 -1
  69. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts +20 -1
  70. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts.map +1 -1
  71. package/dist/document-models/resource-template/v1/gen/audience-management/error.js +16 -1
  72. package/dist/document-models/resource-template/v1/gen/controller.d.ts +4 -0
  73. package/dist/document-models/resource-template/v1/gen/controller.d.ts.map +1 -0
  74. package/dist/document-models/resource-template/v1/gen/controller.js +3 -0
  75. package/dist/document-models/resource-template/v1/gen/document-model.d.ts.map +1 -1
  76. package/dist/document-models/resource-template/v1/gen/document-model.js +207 -89
  77. package/dist/document-models/resource-template/v1/gen/document-schema.d.ts +12 -12
  78. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts +27 -1
  79. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts.map +1 -1
  80. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.js +23 -1
  81. package/dist/document-models/resource-template/v1/gen/index.d.ts +1 -0
  82. package/dist/document-models/resource-template/v1/gen/index.d.ts.map +1 -1
  83. package/dist/document-models/resource-template/v1/gen/index.js +1 -0
  84. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts +27 -1
  85. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts.map +1 -1
  86. package/dist/document-models/resource-template/v1/gen/option-group-management/error.js +23 -1
  87. package/dist/document-models/resource-template/v1/gen/ph-factories.js +3 -3
  88. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts +4 -4
  89. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts.map +1 -1
  90. package/dist/document-models/resource-template/v1/gen/schema/zod.js +4 -4
  91. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts +51 -1
  92. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts.map +1 -1
  93. package/dist/document-models/resource-template/v1/gen/service-management/error.js +49 -1
  94. package/dist/document-models/resource-template/v1/gen/utils.js +3 -3
  95. package/dist/document-models/resource-template/v1/module.d.ts +1 -1
  96. package/dist/document-models/resource-template/v1/module.d.ts.map +1 -1
  97. package/dist/document-models/resource-template/v1/module.js +4 -1
  98. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.d.ts.map +1 -1
  99. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.js +2 -21
  100. package/dist/document-models/service-offering/v1/actions.d.ts +3 -1
  101. package/dist/document-models/service-offering/v1/actions.d.ts.map +1 -1
  102. package/dist/document-models/service-offering/v1/gen/controller.d.ts +4 -0
  103. package/dist/document-models/service-offering/v1/gen/controller.d.ts.map +1 -0
  104. package/dist/document-models/service-offering/v1/gen/controller.js +3 -0
  105. package/dist/document-models/service-offering/v1/gen/document-model.d.ts.map +1 -1
  106. package/dist/document-models/service-offering/v1/gen/document-model.js +421 -199
  107. package/dist/document-models/service-offering/v1/gen/document-schema.d.ts +9 -9
  108. package/dist/document-models/service-offering/v1/gen/index.d.ts +1 -0
  109. package/dist/document-models/service-offering/v1/gen/index.d.ts.map +1 -1
  110. package/dist/document-models/service-offering/v1/gen/index.js +1 -0
  111. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts +41 -1
  112. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts.map +1 -1
  113. package/dist/document-models/service-offering/v1/gen/offering/error.js +37 -1
  114. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts +55 -1
  115. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts.map +1 -1
  116. package/dist/document-models/service-offering/v1/gen/option-groups/error.js +53 -1
  117. package/dist/document-models/service-offering/v1/gen/ph-factories.js +3 -3
  118. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts +134 -61
  119. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts.map +1 -1
  120. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts +35 -10
  121. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts.map +1 -1
  122. package/dist/document-models/service-offering/v1/gen/schema/zod.js +182 -64
  123. package/dist/document-models/service-offering/v1/gen/services/error.d.ts +20 -1
  124. package/dist/document-models/service-offering/v1/gen/services/error.d.ts.map +1 -1
  125. package/dist/document-models/service-offering/v1/gen/services/error.js +16 -1
  126. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts +100 -1
  127. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts.map +1 -1
  128. package/dist/document-models/service-offering/v1/gen/tiers/error.js +106 -1
  129. package/dist/document-models/service-offering/v1/gen/utils.js +4 -4
  130. package/dist/document-models/service-offering/v1/module.d.ts +1 -1
  131. package/dist/document-models/service-offering/v1/module.d.ts.map +1 -1
  132. package/dist/document-models/service-offering/v1/module.js +4 -1
  133. package/dist/document-models/service-offering/v1/src/reducers/offering.d.ts.map +1 -1
  134. package/dist/document-models/service-offering/v1/src/reducers/offering.js +20 -12
  135. package/dist/document-models/service-offering/v1/src/reducers/option-groups.d.ts.map +1 -1
  136. package/dist/document-models/service-offering/v1/src/reducers/option-groups.js +157 -39
  137. package/dist/document-models/service-offering/v1/src/reducers/services.d.ts.map +1 -1
  138. package/dist/document-models/service-offering/v1/src/reducers/services.js +17 -14
  139. package/dist/document-models/service-offering/v1/src/reducers/tiers.d.ts.map +1 -1
  140. package/dist/document-models/service-offering/v1/src/reducers/tiers.js +111 -78
  141. package/dist/document-models/service-offering/v1/src/utils.d.ts +60 -1
  142. package/dist/document-models/service-offering/v1/src/utils.d.ts.map +1 -1
  143. package/dist/document-models/service-offering/v1/src/utils.js +173 -1
  144. package/dist/document-models/service-offering/v1/tests/option-groups.test.js +1 -1
  145. package/dist/document-models/service-offering/v1/utils.d.ts +3 -0
  146. package/dist/document-models/service-offering/v1/utils.d.ts.map +1 -1
  147. package/dist/document-models/subscription-instance/v1/actions.d.ts +3 -1
  148. package/dist/document-models/subscription-instance/v1/actions.d.ts.map +1 -1
  149. package/dist/document-models/subscription-instance/v1/gen/controller.d.ts +4 -0
  150. package/dist/document-models/subscription-instance/v1/gen/controller.d.ts.map +1 -0
  151. package/dist/document-models/subscription-instance/v1/gen/controller.js +3 -0
  152. package/dist/document-models/subscription-instance/v1/gen/document-model.d.ts.map +1 -1
  153. package/dist/document-models/subscription-instance/v1/gen/document-model.js +488 -246
  154. package/dist/document-models/subscription-instance/v1/gen/document-schema.d.ts +3 -3
  155. package/dist/document-models/subscription-instance/v1/gen/index.d.ts +1 -0
  156. package/dist/document-models/subscription-instance/v1/gen/index.d.ts.map +1 -1
  157. package/dist/document-models/subscription-instance/v1/gen/index.js +1 -0
  158. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts +73 -1
  159. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts.map +1 -1
  160. package/dist/document-models/subscription-instance/v1/gen/metrics/error.js +86 -1
  161. package/dist/document-models/subscription-instance/v1/gen/ph-factories.js +1 -1
  162. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts +199 -82
  163. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts.map +1 -1
  164. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts +22 -12
  165. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts.map +1 -1
  166. package/dist/document-models/subscription-instance/v1/gen/schema/zod.js +230 -84
  167. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts +62 -1
  168. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts.map +1 -1
  169. package/dist/document-models/subscription-instance/v1/gen/service/error.js +60 -1
  170. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts +39 -1
  171. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts.map +1 -1
  172. package/dist/document-models/subscription-instance/v1/gen/service-group/error.js +39 -1
  173. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts +55 -1
  174. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts.map +1 -1
  175. package/dist/document-models/subscription-instance/v1/gen/subscription/error.js +51 -1
  176. package/dist/document-models/subscription-instance/v1/gen/utils.js +2 -2
  177. package/dist/document-models/subscription-instance/v1/module.d.ts +1 -1
  178. package/dist/document-models/subscription-instance/v1/module.d.ts.map +1 -1
  179. package/dist/document-models/subscription-instance/v1/module.js +4 -1
  180. package/dist/document-models/subscription-instance/v1/src/reducers/customer.d.ts.map +1 -1
  181. package/dist/document-models/subscription-instance/v1/src/reducers/customer.js +1 -0
  182. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.d.ts.map +1 -1
  183. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.js +70 -45
  184. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.d.ts.map +1 -1
  185. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.js +108 -30
  186. package/dist/document-models/subscription-instance/v1/src/reducers/service.d.ts.map +1 -1
  187. package/dist/document-models/subscription-instance/v1/src/reducers/service.js +108 -39
  188. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.d.ts.map +1 -1
  189. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.js +193 -35
  190. package/dist/editors/resource-instance-editor/editor.d.ts.map +1 -1
  191. package/dist/editors/resource-instance-editor/editor.js +13 -3
  192. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.d.ts.map +1 -1
  193. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.js +4 -2
  194. package/dist/editors/service-offering-editor/components/ServiceCatalog.d.ts.map +1 -1
  195. package/dist/editors/service-offering-editor/components/ServiceCatalog.js +189 -32
  196. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts +1 -1
  197. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts.map +1 -1
  198. package/dist/editors/service-offering-editor/components/TheMatrix.js +295 -140
  199. package/dist/editors/service-offering-editor/components/TierDefinition.d.ts.map +1 -1
  200. package/dist/editors/service-offering-editor/components/TierDefinition.js +2 -0
  201. package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.js +3 -3
  202. package/dist/editors/service-offering-editor/components/pricing-utils.d.ts.map +1 -1
  203. package/dist/editors/service-offering-editor/components/pricing-utils.js +26 -7
  204. package/dist/editors/subscription-instance-editor/components/BillingPanel.d.ts.map +1 -1
  205. package/dist/editors/subscription-instance-editor/components/BillingPanel.js +4 -4
  206. package/dist/editors/subscription-instance-editor/components/CustomerInfo.d.ts.map +1 -1
  207. package/dist/editors/subscription-instance-editor/components/CustomerInfo.js +3 -2
  208. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts +3 -0
  209. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts.map +1 -1
  210. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.js +12 -0
  211. package/dist/editors/subscription-instance-editor/components/MetricActions.d.ts.map +1 -1
  212. package/dist/editors/subscription-instance-editor/components/MetricActions.js +4 -2
  213. package/dist/editors/subscription-instance-editor/components/MockDataButton.d.ts.map +1 -1
  214. package/dist/editors/subscription-instance-editor/components/MockDataButton.js +214 -2
  215. package/dist/editors/subscription-instance-editor/components/OperatorNotes.js +1 -1
  216. package/dist/editors/subscription-instance-editor/components/ServicesPanel.d.ts.map +1 -1
  217. package/dist/editors/subscription-instance-editor/components/ServicesPanel.js +9 -20
  218. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.d.ts.map +1 -1
  219. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.js +8 -9
  220. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.d.ts.map +1 -1
  221. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.js +1 -1
  222. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts +14 -6
  223. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts.map +1 -1
  224. package/dist/editors/subscription-instance-editor/components/billing-utils.js +19 -23
  225. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts +16 -2
  226. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts.map +1 -1
  227. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.js +155 -6
  228. package/dist/powerhouse.manifest.json +29 -3
  229. package/dist/style.css +14 -0
  230. package/dist/subgraphs/resources-services/resolvers.d.ts +1 -1
  231. package/dist/subgraphs/resources-services/resolvers.d.ts.map +1 -1
  232. package/dist/subgraphs/resources-services/resolvers.js +272 -158
  233. package/dist/subgraphs/resources-services/schema.d.ts.map +1 -1
  234. package/dist/subgraphs/resources-services/schema.js +107 -41
  235. package/package.json +22 -18
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { MetricActions } from "./MetricActions.js";
3
- import { formatCurrency as fmtCurrency } from "./billing-utils.js";
4
- function UsageBar({ serviceId, metric, dispatch, isOperator, customerName, currency, }) {
3
+ import { formatCurrency as fmtCurrency, formatBillingCycleSuffix, formatDiscountBadge, } from "./billing-utils.js";
4
+ function UsageBar({ serviceId, metric, dispatch, isOperator, customerName, }) {
5
5
  const freeLimit = metric.freeLimit ?? metric.limit ?? 0;
6
6
  const paidLimit = metric.paidLimit ?? null;
7
7
  const displayLimit = paidLimit ?? freeLimit;
@@ -17,35 +17,24 @@ function UsageBar({ serviceId, metric, dispatch, isOperator, customerName, curre
17
17
  return "si-usage-bar__fill--normal";
18
18
  };
19
19
  const isOverFree = metric.currentUsage > freeLimit && freeLimit > 0;
20
- return (_jsxs("div", { className: "si-metric", children: [_jsxs("div", { className: "si-metric__header", children: [_jsx("span", { className: "si-metric__name", children: metric.name }), _jsxs("span", { className: "si-metric__value", children: [metric.currentUsage.toLocaleString(), displayLimit > 0 && ` / ${displayLimit.toLocaleString()}`, _jsxs("span", { className: "si-metric__unit", children: [" ", metric.unitName] })] })] }), _jsxs("div", { className: "si-metric__body", children: [displayLimit > 0 && (_jsxs("div", { className: "si-usage-bar", children: [paidLimit != null && freeLimit > 0 && freeLimit < paidLimit && (_jsx("div", { className: "si-usage-bar__free-marker", style: { left: `${freePortion}%` }, title: `${freeLimit.toLocaleString()} free` })), _jsx("div", { className: `si-usage-bar__fill ${getBarColor()}`, style: { width: `${percentage}%` }, role: "progressbar", "aria-valuenow": metric.currentUsage, "aria-valuemin": 0, "aria-valuemax": displayLimit })] })), _jsx(MetricActions, { serviceId: serviceId, metric: metric, dispatch: dispatch, isOperator: isOperator, customerName: customerName })] }), paidLimit != null && freeLimit > 0 && freeLimit !== paidLimit && (_jsxs("p", { className: "si-metric__paid-limit", children: [freeLimit.toLocaleString(), " free \u00B7 ", paidLimit.toLocaleString(), " max", metric.unitCost != null && (_jsxs("span", { children: [" · ", "overage: ", fmtCurrency(metric.unitCost, currency), "/", metric.unitName] }))] })), isOverFree && metric.unitCost != null && (_jsxs("div", { className: "si-metric__overage", children: [_jsx("strong", { children: (metric.currentUsage - freeLimit).toLocaleString() }), " ", metric.unitName, " over free limit"] })), (metric.nextUsageReset || metric.usageResetPeriod) && (_jsxs("p", { className: "si-metric__reset", children: [metric.usageResetPeriod && (_jsxs("span", { className: "si-metric__reset-period", children: [metric.usageResetPeriod.charAt(0) +
20
+ return (_jsxs("div", { className: "si-metric", children: [_jsxs("div", { className: "si-metric__header", children: [_jsx("span", { className: "si-metric__name", children: metric.name }), _jsxs("span", { className: "si-metric__value", children: [metric.currentUsage.toLocaleString(), displayLimit > 0 && ` / ${displayLimit.toLocaleString()}`, _jsxs("span", { className: "si-metric__unit", children: [" ", metric.unitName] })] })] }), _jsxs("div", { className: "si-metric__body", children: [displayLimit > 0 && (_jsxs("div", { className: "si-usage-bar", children: [paidLimit != null && freeLimit > 0 && freeLimit < paidLimit && (_jsx("div", { className: "si-usage-bar__free-marker", style: { left: `${freePortion}%` }, title: `${freeLimit.toLocaleString()} free` })), _jsx("div", { className: `si-usage-bar__fill ${getBarColor()}`, style: { width: `${percentage}%` }, role: "progressbar", "aria-valuenow": metric.currentUsage, "aria-valuemin": 0, "aria-valuemax": displayLimit })] })), _jsx(MetricActions, { serviceId: serviceId, metric: metric, dispatch: dispatch, isOperator: isOperator, customerName: customerName })] }), paidLimit != null && freeLimit > 0 && freeLimit !== paidLimit && (_jsxs("p", { className: "si-metric__paid-limit", children: [freeLimit.toLocaleString(), " free \u00B7 ", paidLimit.toLocaleString(), " max", metric.unitCost && (_jsxs("span", { children: [" · ", "overage:", " ", fmtCurrency(metric.unitCost.amount, metric.unitCost.currency), "/", metric.unitName] }))] })), isOverFree && metric.unitCost && (_jsxs("div", { className: "si-metric__overage", children: [_jsx("strong", { children: (metric.currentUsage - freeLimit).toLocaleString() }), " ", metric.unitName, " over free limit"] })), (metric.nextUsageReset || metric.usageResetPeriod) && (_jsxs("p", { className: "si-metric__reset", children: [metric.usageResetPeriod && (_jsxs("span", { className: "si-metric__reset-period", children: [metric.usageResetPeriod.charAt(0) +
21
21
  metric.usageResetPeriod.slice(1).toLowerCase(), " ", "reset"] })), metric.nextUsageReset && (_jsxs("span", { children: [metric.usageResetPeriod ? " · " : "Resets ", new Date(metric.nextUsageReset).toLocaleDateString()] }))] }))] }));
22
22
  }
23
- function ServiceCard({ service, mode, dispatch, customerName, currency, }) {
24
- return (_jsxs("div", { className: "si-service-card", children: [_jsxs("div", { className: "si-service-card__header", children: [_jsx("h4", { className: "si-service-card__name", children: service.name || "Service" }), service.customValue && (_jsx("span", { className: "si-service-card__custom-value", children: service.customValue }))] }), service.description && (_jsx("p", { className: "si-service-card__desc", children: service.description })), service.metrics.length > 0 && (_jsx("div", { className: "si-service-card__metrics", children: service.metrics.map((metric) => (_jsx(UsageBar, { serviceId: service.id, metric: metric, dispatch: dispatch, isOperator: mode === "operator", customerName: customerName, currency: currency }, metric.id))) }))] }));
23
+ function ServiceCard({ service, mode, dispatch, customerName, }) {
24
+ return (_jsxs("div", { className: "si-service-card", children: [_jsxs("div", { className: "si-service-card__header", children: [_jsx("h4", { className: "si-service-card__name", children: service.name || "Service" }), service.customValue && (_jsx("span", { className: "si-service-card__custom-value", children: service.customValue }))] }), service.description && (_jsx("p", { className: "si-service-card__desc", children: service.description })), service.metrics.length > 0 && (_jsx("div", { className: "si-service-card__metrics", children: service.metrics.map((metric) => (_jsx(UsageBar, { serviceId: service.id, metric: metric, dispatch: dispatch, isOperator: mode === "operator", customerName: customerName }, metric.id))) }))] }));
25
25
  }
26
26
  export function ServicesPanel({ document, dispatch, mode, }) {
27
27
  const state = document.state.global;
28
- const currency = state.globalCurrency || state.tierCurrency || "USD";
29
- const allGroupedServiceIds = new Set(state.serviceGroups.flatMap((g) => g.services));
30
- const standaloneServices = state.services.filter((s) => !allGroupedServiceIds.has(s.id));
28
+ // Split groups into recurring (non-optional) and add-ons (optional)
31
29
  const recurringGroups = state.serviceGroups.filter((g) => !g.optional);
32
30
  const addonGroups = state.serviceGroups.filter((g) => g.optional);
33
- const hasRecurring = standaloneServices.length > 0 || recurringGroups.length > 0;
31
+ const hasRecurring = state.services.length > 0 || recurringGroups.length > 0;
34
32
  const hasAddons = addonGroups.length > 0;
35
- const recurringServiceCount = standaloneServices.length +
33
+ const recurringServiceCount = state.services.length +
36
34
  recurringGroups.reduce((acc, g) => acc + g.services.length, 0);
37
35
  const addonServiceCount = addonGroups.reduce((acc, g) => acc + g.services.length, 0);
38
36
  if (!hasRecurring && !hasAddons) {
39
37
  return (_jsxs("div", { className: "si-panel", children: [_jsx("div", { className: "si-panel__header", children: _jsx("h3", { className: "si-panel__title", children: "Services" }) }), _jsxs("div", { className: "si-empty", children: [_jsx("svg", { className: "si-empty__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }), _jsx("p", { className: "si-empty__text", children: "No services configured" })] })] }));
40
38
  }
41
- const resolveGroupServices = (serviceIds) => serviceIds
42
- .map((id) => state.services.find((s) => s.id === id))
43
- .filter((s) => s != null);
44
- return (_jsxs(_Fragment, { children: [hasRecurring && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Recurring Services" }), _jsxs("span", { className: "si-panel__count", children: [recurringServiceCount, " services"] })] }), standaloneServices.length > 0 && (_jsx("div", { className: "si-services-grid", children: standaloneServices.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName, currency: currency }, service.id))) })), recurringGroups.map((group) => {
45
- const groupServices = resolveGroupServices(group.services);
46
- return (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), group.recurringCost && (_jsx("span", { className: "si-service-group__price", children: fmtCurrency(group.recurringCost.amount, group.recurringCost.currency) }))] }), _jsx("div", { className: "si-services-grid", children: groupServices.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName, currency: currency }, service.id))) })] }, group.id));
47
- })] })), hasAddons && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Add-ons" }), _jsxs("span", { className: "si-panel__count", children: [addonGroups.length, " groups, ", addonServiceCount, " services"] })] }), addonGroups.map((group) => {
48
- const groupServices = resolveGroupServices(group.services);
49
- return (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), _jsx("span", { className: "si-badge si-badge--violet si-badge--sm", children: "Optional" }), group.recurringCost && (_jsx("span", { className: "si-service-group__price", children: fmtCurrency(group.recurringCost.amount, group.recurringCost.currency) }))] }), _jsx("div", { className: "si-services-grid", children: groupServices.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName, currency: currency }, service.id))) })] }, group.id));
50
- })] }))] }));
39
+ return (_jsxs(_Fragment, { children: [hasRecurring && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Recurring Services" }), _jsxs("span", { className: "si-panel__count", children: [recurringServiceCount, " services"] })] }), state.services.length > 0 && (_jsx("div", { className: "si-services-grid", children: state.services.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName }, service.id))) })), recurringGroups.map((group) => (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), group.recurringCost && (_jsxs("span", { className: "si-service-group__price", children: [group.recurringCost.discount && (_jsxs(_Fragment, { children: [_jsx("span", { className: "si-service-group__original-price", children: fmtCurrency(group.recurringCost.discount.originalAmount, group.recurringCost.currency) }), _jsx("span", { className: "si-service-group__discount-badge", children: formatDiscountBadge(group.recurringCost.discount) })] })), fmtCurrency(group.recurringCost.amount, group.recurringCost.currency), formatBillingCycleSuffix(group.recurringCost.billingCycle)] }))] }), _jsx("div", { className: "si-services-grid", children: group.services.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName }, service.id))) })] }, group.id)))] })), hasAddons && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Add-ons" }), _jsxs("span", { className: "si-panel__count", children: [addonGroups.length, " groups, ", addonServiceCount, " services"] })] }), addonGroups.map((group) => (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), _jsx("span", { className: "si-badge si-badge--violet si-badge--sm", children: "Optional" }), group.recurringCost && (_jsxs("span", { className: "si-service-group__price", children: [group.recurringCost.discount && (_jsxs(_Fragment, { children: [_jsx("span", { className: "si-service-group__original-price", children: fmtCurrency(group.recurringCost.discount.originalAmount, group.recurringCost.currency) }), _jsx("span", { className: "si-service-group__discount-badge", children: formatDiscountBadge(group.recurringCost.discount) })] })), fmtCurrency(group.recurringCost.amount, group.recurringCost.currency), formatBillingCycleSuffix(group.recurringCost.billingCycle)] }))] }), _jsx("div", { className: "si-services-grid", children: group.services.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName }, service.id))) })] }, group.id)))] }))] }));
51
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionActions.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionActions.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAS5C,UAAU,wBAAwB;IAChC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAsED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,wBAAwB,2CA2P1B"}
1
+ {"version":3,"file":"SubscriptionActions.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionActions.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAS5C,UAAU,wBAAwB;IAChC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAsED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,wBAAwB,2CA2P1B"}
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState, useCallback } from "react";
3
- import { generateId } from "document-model/core";
4
3
  import { activateSubscription, pauseSubscription, resumeSubscription, cancelSubscription, renewExpiringSubscription, } from "../../../document-models/subscription-instance/v1/gen/subscription/creators.js";
5
4
  function ConfirmModal({ isOpen, title, message, confirmLabel, confirmVariant = "primary", onConfirm, onCancel, showReasonInput, reason, onReasonChange, }) {
6
5
  if (!isOpen)
@@ -19,32 +18,32 @@ export function SubscriptionActions({ document, dispatch, mode, }) {
19
18
  // Operator direct actions
20
19
  const handleActivate = useCallback(() => {
21
20
  dispatch(activateSubscription({
22
- activatedAt: new Date().toISOString(),
21
+ activatedSince: new Date().toISOString(),
23
22
  }));
24
23
  }, [dispatch]);
25
24
  const handleOperatorPause = useCallback(() => {
26
25
  dispatch(pauseSubscription({
27
- pausedAt: new Date().toISOString(),
26
+ pausedSince: new Date().toISOString(),
28
27
  }));
29
28
  setConfirmAction(null);
30
29
  }, [dispatch]);
31
30
  const handleOperatorResume = useCallback(() => {
32
31
  dispatch(resumeSubscription({
33
- resumedAt: new Date().toISOString(),
32
+ timestamp: new Date().toISOString(),
34
33
  }));
35
34
  setConfirmAction(null);
36
35
  }, [dispatch]);
37
36
  const handleOperatorCancel = useCallback(() => {
38
37
  dispatch(cancelSubscription({
39
- cancelledAt: new Date().toISOString(),
40
- reason: reason || undefined,
38
+ cancelledSince: new Date().toISOString(),
39
+ cancellationReason: reason || null,
41
40
  }));
42
41
  setConfirmAction(null);
43
42
  setReason("");
44
43
  }, [dispatch, reason]);
45
44
  const handleOperatorRenew = useCallback(() => {
46
45
  dispatch(renewExpiringSubscription({
47
- renewedAt: new Date().toISOString(),
46
+ timestamp: new Date().toISOString(),
48
47
  }));
49
48
  setConfirmAction(null);
50
49
  }, [dispatch]);
@@ -70,12 +69,12 @@ export function SubscriptionActions({ document, dispatch, mode, }) {
70
69
  handleOperatorCancel,
71
70
  handleOperatorRenew,
72
71
  ]);
73
- const isDraft = state.status === "DRAFT";
72
+ const isPending = state.status === "PENDING";
74
73
  const isActive = state.status === "ACTIVE";
75
74
  const isPaused = state.status === "PAUSED";
76
75
  const isExpiring = state.status === "EXPIRING";
77
76
  const isCancelled = state.status === "CANCELLED";
78
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "si-actions", children: mode === "operator" && (_jsxs("div", { className: "si-actions__buttons", children: [isDraft && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: handleActivate, children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }), "Activate"] })), isActive && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--warning", onClick: () => setConfirmAction("pause"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z", clipRule: "evenodd" }) }), "Pause"] })), isPaused && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: () => setConfirmAction("resume"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z", clipRule: "evenodd" }) }), "Resume"] })), isExpiring && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--primary", onClick: () => setConfirmAction("renew"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z", clipRule: "evenodd" }) }), "Renew"] })), !isCancelled && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--danger-ghost", onClick: () => setConfirmAction("cancel"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" }) }), "Cancel"] }))] })) }), _jsx(ConfirmModal, { isOpen: confirmAction === "pause", title: "Pause Subscription", message: "Are you sure you want to pause this subscription? Services will be temporarily suspended.", confirmLabel: "Pause Subscription", confirmVariant: "warning", onConfirm: handleConfirm, onCancel: () => {
77
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "si-actions", children: mode === "operator" && (_jsxs("div", { className: "si-actions__buttons", children: [isPending && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: handleActivate, children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }), "Activate"] })), isActive && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--warning", onClick: () => setConfirmAction("pause"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z", clipRule: "evenodd" }) }), "Pause"] })), isPaused && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: () => setConfirmAction("resume"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z", clipRule: "evenodd" }) }), "Resume"] })), isExpiring && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--primary", onClick: () => setConfirmAction("renew"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z", clipRule: "evenodd" }) }), "Renew"] })), !isCancelled && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--danger-ghost", onClick: () => setConfirmAction("cancel"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" }) }), "Cancel"] }))] })) }), _jsx(ConfirmModal, { isOpen: confirmAction === "pause", title: "Pause Subscription", message: "Are you sure you want to pause this subscription? Services will be temporarily suspended.", confirmLabel: "Pause Subscription", confirmVariant: "warning", onConfirm: handleConfirm, onCancel: () => {
79
78
  setConfirmAction(null);
80
79
  setReason("");
81
80
  } }), _jsx(ConfirmModal, { isOpen: confirmAction === "resume", title: "Resume Subscription", message: "Are you sure you want to resume this subscription? Services will be reactivated.", confirmLabel: "Resume Subscription", confirmVariant: "primary", onConfirm: handleConfirm, onCancel: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionHeader.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiD5C,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,uBAAuB,2CAwIzB"}
1
+ {"version":3,"file":"SubscriptionHeader.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiD5C,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,uBAAuB,2CAkJzB"}
@@ -40,7 +40,7 @@ export function SubscriptionHeader({ document, dispatch, mode, }) {
40
40
  year: "numeric",
41
41
  });
42
42
  };
43
- return (_jsxs("div", { className: "si-header", children: [_jsxs("div", { className: "si-header__main", children: [_jsxs("div", { className: "si-header__title-row", children: [_jsx("div", { className: "si-header__info", children: _jsx("div", { children: _jsx("h1", { className: "si-header__title", children: state.tierName || "Subscription" }) }) }), _jsx(StatusBadge, { status: state.status })] }), _jsxs("div", { className: "si-header__meta", children: [mode === "operator" && state.customerName && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Customer" }), _jsx("span", { className: "si-header__meta-value", children: state.customerName })] })), state.createdAt && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Created" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.createdAt) })] })), state.activatedSince && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Active Since" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.activatedSince) })] })), _jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Auto-Renew" }), _jsx("span", { className: "si-header__meta-value", style: {
43
+ return (_jsxs("div", { className: "si-header", children: [_jsxs("div", { className: "si-header__main", children: [_jsxs("div", { className: "si-header__title-row", children: [_jsxs("div", { className: "si-header__info", children: [state.resource?.thumbnailUrl && (_jsx("img", { src: state.resource.thumbnailUrl, alt: "", className: "si-header__thumbnail" })), _jsxs("div", { children: [_jsx("h1", { className: "si-header__title", children: state.resource?.label || state.tierName || "Subscription" }), state.tierName && state.resource?.label && (_jsxs("p", { className: "si-header__subtitle", children: [state.tierName, " Tier"] }))] })] }), _jsx(StatusBadge, { status: state.status })] }), _jsxs("div", { className: "si-header__meta", children: [mode === "operator" && state.customerName && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Customer" }), _jsx("span", { className: "si-header__meta-value", children: state.customerName })] })), state.createdAt && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Created" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.createdAt) })] })), state.activatedSince && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Active Since" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.activatedSince) })] })), _jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Auto-Renew" }), _jsx("span", { className: "si-header__meta-value", style: {
44
44
  color: state.autoRenew
45
45
  ? "var(--si-emerald-600)"
46
46
  : "var(--si-slate-400)",
@@ -1,12 +1,9 @@
1
- import type { SubscriptionInstanceState, ServiceMetric } from "../../../document-models/subscription-instance/v1/gen/schema/types.js";
1
+ import type { SubscriptionInstanceState, ServiceMetric, DiscountInfo } from "../../../document-models/subscription-instance/v1/gen/schema/types.js";
2
2
  export declare function formatCurrency(amount: number, currency: string): string;
3
3
  export declare function formatDate(date: string | null | undefined): string;
4
4
  export declare function formatBillingCycleSuffix(cycle: string | null | undefined): string;
5
5
  export declare const BILLING_CYCLE_LABELS: Record<string, string>;
6
- export declare function formatDiscountBadge(discount: {
7
- discountType: string;
8
- discountValue: number;
9
- }): string;
6
+ export declare function formatDiscountBadge(discount: DiscountInfo): string;
10
7
  export declare function getDiscountSourceLabel(source: string): string;
11
8
  export interface MetricOverage {
12
9
  metricId: string;
@@ -20,13 +17,17 @@ export interface MetricOverage {
20
17
  unitCostCurrency: string;
21
18
  projectedCost: number;
22
19
  }
23
- export declare function computeMetricOverage(metric: ServiceMetric, currency?: string): MetricOverage | null;
20
+ export declare function computeMetricOverage(metric: ServiceMetric): MetricOverage | null;
24
21
  export interface GroupBillingBreakdown {
25
22
  groupId: string;
26
23
  groupName: string;
27
24
  optional: boolean;
25
+ /** Group-level recurring cost (fixed cost) */
28
26
  recurringAmount: number | null;
29
27
  recurringCurrency: string;
28
+ recurringCycle: string | null;
29
+ discount: DiscountInfo | null;
30
+ /** Dynamic costs from service metrics */
30
31
  metricOverages: MetricOverage[];
31
32
  dynamicTotal: number;
32
33
  }
@@ -39,12 +40,19 @@ export interface SetupCostLine {
39
40
  }
40
41
  export interface BillingBreakdown {
41
42
  currency: string;
43
+ /** Sum of group recurring costs */
42
44
  fixedTotal: number;
45
+ /** Sum of metric overage projections */
43
46
  dynamicTotal: number;
47
+ /** fixedTotal + dynamicTotal */
44
48
  projectedTotal: number;
49
+ /** Standalone service recurring costs (not in groups) */
45
50
  standaloneFixedTotal: number;
51
+ /** Breakdown per service group */
46
52
  groupBreakdowns: GroupBillingBreakdown[];
53
+ /** Standalone services with metrics */
47
54
  standaloneOverages: MetricOverage[];
55
+ /** All setup costs */
48
56
  setupLines: SetupCostLine[];
49
57
  setupTotal: number;
50
58
  billingCycle: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"billing-utils.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/billing-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACd,MAAM,uEAAuE,CAAC;AAI/E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAOlE;AAUD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,CAGR;AAED,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMvD,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAKT;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAID,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,QAAQ,GAAE,MAAc,GACvB,aAAa,GAAG,IAAI,CAuBtB;AAID,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,yBAAyB,GAC/B,gBAAgB,CA8GlB"}
1
+ {"version":3,"file":"billing-utils.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/billing-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACb,YAAY,EACb,MAAM,uEAAuE,CAAC;AAI/E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAOlE;AAUD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,CAGR;AAED,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMvD,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAKlE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAID,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,GACpB,aAAa,GAAG,IAAI,CAuBtB;AAID,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,yCAAyC;IACzC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,uCAAuC;IACvC,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,sBAAsB;IACtB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,yBAAyB,GAC/B,gBAAgB,CAuGlB"}
@@ -52,48 +52,41 @@ export function getDiscountSourceLabel(source) {
52
52
  return "Discount";
53
53
  }
54
54
  }
55
- export function computeMetricOverage(metric, currency = "USD") {
55
+ export function computeMetricOverage(metric) {
56
56
  const freeLimit = metric.freeLimit ?? metric.limit ?? 0;
57
57
  const paidLimit = metric.paidLimit ?? null;
58
58
  if (freeLimit <= 0 && paidLimit == null)
59
59
  return null;
60
60
  if (metric.currentUsage <= freeLimit)
61
61
  return null;
62
- if (metric.unitCost == null)
62
+ if (!metric.unitCost)
63
63
  return null;
64
64
  const excess = metric.currentUsage - freeLimit;
65
- const projectedCost = excess * metric.unitCost;
65
+ const projectedCost = excess * metric.unitCost.amount;
66
66
  return {
67
67
  metricId: metric.id,
68
68
  metricName: metric.name,
69
- unitName: metric.unitName ?? "units",
69
+ unitName: metric.unitName,
70
70
  currentUsage: metric.currentUsage,
71
71
  freeLimit,
72
72
  paidLimit,
73
73
  excess,
74
- unitCostAmount: metric.unitCost,
75
- unitCostCurrency: currency,
74
+ unitCostAmount: metric.unitCost.amount,
75
+ unitCostCurrency: metric.unitCost.currency,
76
76
  projectedCost,
77
77
  };
78
78
  }
79
79
  export function computeBillingBreakdown(state) {
80
80
  const currency = state.globalCurrency || state.tierCurrency || "USD";
81
81
  const billingCycle = state.selectedBillingCycle || null;
82
+ // Group breakdowns
82
83
  const groupBreakdowns = [];
83
84
  const setupLines = [];
84
- const allGroupedServiceIds = new Set();
85
- for (const group of state.serviceGroups) {
86
- for (const svcId of group.services) {
87
- allGroupedServiceIds.add(svcId);
88
- }
89
- }
90
85
  for (const group of state.serviceGroups) {
91
86
  const metricOverages = [];
92
- const groupServiceIds = new Set(group.services);
93
- const groupServices = state.services.filter((svc) => groupServiceIds.has(svc.id));
94
- for (const svc of groupServices) {
87
+ for (const svc of group.services) {
95
88
  for (const metric of svc.metrics) {
96
- const overage = computeMetricOverage(metric, currency);
89
+ const overage = computeMetricOverage(metric);
97
90
  if (overage)
98
91
  metricOverages.push(overage);
99
92
  }
@@ -105,40 +98,43 @@ export function computeBillingBreakdown(state) {
105
98
  optional: group.optional,
106
99
  recurringAmount: group.recurringCost?.amount ?? null,
107
100
  recurringCurrency: group.recurringCost?.currency ?? currency,
101
+ recurringCycle: group.recurringCost?.billingCycle ?? billingCycle,
102
+ discount: group.recurringCost?.discount ?? null,
108
103
  metricOverages,
109
104
  dynamicTotal,
110
105
  });
106
+ // Collect setup costs from group level
111
107
  if (group.setupCost) {
112
108
  setupLines.push({
113
109
  name: group.name,
114
110
  amount: group.setupCost.amount,
115
111
  currency: group.setupCost.currency,
116
- paid: !!group.setupCost.paidAt,
112
+ paid: !!group.setupCost.paymentDate,
117
113
  source: "group",
118
114
  });
119
115
  }
120
- for (const svc of groupServices) {
116
+ // Collect setup costs from services in group
117
+ for (const svc of group.services) {
121
118
  if (svc.setupCost) {
122
119
  setupLines.push({
123
120
  name: `${svc.name || "Service"} (${group.name})`,
124
121
  amount: svc.setupCost.amount,
125
122
  currency: svc.setupCost.currency,
126
- paid: !!svc.setupCost.paidAt,
123
+ paid: !!svc.setupCost.paymentDate,
127
124
  source: "service",
128
125
  });
129
126
  }
130
127
  }
131
128
  }
129
+ // Standalone services (not in groups)
132
130
  const standaloneOverages = [];
133
131
  let standaloneFixedTotal = 0;
134
132
  for (const svc of state.services) {
135
- if (allGroupedServiceIds.has(svc.id))
136
- continue;
137
133
  if (svc.recurringCost) {
138
134
  standaloneFixedTotal += svc.recurringCost.amount;
139
135
  }
140
136
  for (const metric of svc.metrics) {
141
- const overage = computeMetricOverage(metric, currency);
137
+ const overage = computeMetricOverage(metric);
142
138
  if (overage)
143
139
  standaloneOverages.push(overage);
144
140
  }
@@ -147,7 +143,7 @@ export function computeBillingBreakdown(state) {
147
143
  name: svc.name || "Service",
148
144
  amount: svc.setupCost.amount,
149
145
  currency: svc.setupCost.currency,
150
- paid: !!svc.setupCost.paidAt,
146
+ paid: !!svc.setupCost.paymentDate,
151
147
  source: "service",
152
148
  });
153
149
  }
@@ -1,18 +1,32 @@
1
1
  import type { ServiceOfferingState } from "../../../document-models/service-offering/v1/gen/schema/types.js";
2
+ import type { PriceBreakdown } from "../../../document-models/service-offering/v1/src/utils.js";
2
3
  import type { InitializeSubscriptionInput, BillingCycle as SIBillingCycle } from "../../../document-models/subscription-instance/v1/gen/schema/types.js";
3
4
  export interface MapOfferingOptions {
5
+ /** The service offering state to import from */
4
6
  offering: ServiceOfferingState;
7
+ /** The selected tier ID */
5
8
  tierId: string;
9
+ /** The selected global billing cycle */
6
10
  selectedBillingCycle: SIBillingCycle;
11
+ /** Customer info */
7
12
  customerId?: string;
8
13
  customerName?: string;
9
14
  customerEmail?: string;
15
+ /** Timestamp for createdAt */
10
16
  createdAt: string;
17
+ /** Computed price breakdown from getUserSelectionPriceBreakdown */
18
+ priceBreakdown: PriceBreakdown;
11
19
  }
12
20
  /**
13
21
  * Maps a Service Offering state to an InitializeSubscriptionInput.
14
- * This creates the basic subscription shell services and groups
15
- * must be added via separate actions after initialization.
22
+ * This is a one-time snapshotthe SI lives independently after creation.
23
+ *
24
+ * Logic:
25
+ * 1. Find the selected tier and resolve pricing from priceBreakdown
26
+ * 2. Map option group breakdowns from priceBreakdown as service groups
27
+ * 3. Map add-on breakdowns from priceBreakdown as optional service groups
28
+ * 4. Map remaining standalone services with tier service levels and usage limits
29
+ * 5. Calculate tier price from breakdown or service group sums (CALCULATED) or manual price
16
30
  */
17
31
  export declare function mapOfferingToSubscription(options: MapOfferingOptions): InitializeSubscriptionInput;
18
32
  //# sourceMappingURL=mapOfferingToSubscription.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mapOfferingToSubscription.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/mapOfferingToSubscription.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAErB,MAAM,kEAAkE,CAAC;AAC1E,OAAO,KAAK,EACV,2BAA2B,EAC3B,YAAY,IAAI,cAAc,EAC/B,MAAM,uEAAuE,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,cAAc,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,kBAAkB,GAC1B,2BAA2B,CAkC7B"}
1
+ {"version":3,"file":"mapOfferingToSubscription.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/mapOfferingToSubscription.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,kEAAkE,CAAC;AAC1E,OAAO,KAAK,EACV,cAAc,EAEf,MAAM,2DAA2D,CAAC;AACnE,OAAO,KAAK,EACV,2BAA2B,EAM3B,YAAY,IAAI,cAAc,EAC/B,MAAM,uEAAuE,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,oBAAoB,EAAE,cAAc,CAAC;IACrC,oBAAoB;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,cAAc,EAAE,cAAc,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,kBAAkB,GAC1B,2BAA2B,CA4E7B"}
@@ -1,17 +1,47 @@
1
+ import { generateId } from "document-model/core";
1
2
  /**
2
3
  * Maps a Service Offering state to an InitializeSubscriptionInput.
3
- * This creates the basic subscription shell services and groups
4
- * must be added via separate actions after initialization.
4
+ * This is a one-time snapshotthe SI lives independently after creation.
5
+ *
6
+ * Logic:
7
+ * 1. Find the selected tier and resolve pricing from priceBreakdown
8
+ * 2. Map option group breakdowns from priceBreakdown as service groups
9
+ * 3. Map add-on breakdowns from priceBreakdown as optional service groups
10
+ * 4. Map remaining standalone services with tier service levels and usage limits
11
+ * 5. Calculate tier price from breakdown or service group sums (CALCULATED) or manual price
5
12
  */
6
13
  export function mapOfferingToSubscription(options) {
7
- const { offering, tierId, selectedBillingCycle, customerId, customerName, customerEmail, createdAt, } = options;
14
+ const { offering, tierId, selectedBillingCycle, customerId, customerName, customerEmail, createdAt, priceBreakdown, } = options;
8
15
  const tier = offering.tiers.find((t) => t.id === tierId);
9
16
  if (!tier) {
10
17
  throw new Error(`Tier ${tierId} not found in offering`);
11
18
  }
12
- const currency = tier.pricing?.currency ?? "USD";
13
- const pricingMode = tier.pricingMode;
14
- const tierPrice = tier.pricing?.amount ?? undefined;
19
+ const currency = priceBreakdown.tierCurrency || tier.pricing.currency;
20
+ const pricingMode = tier.pricingMode || "MANUAL_OVERRIDE";
21
+ // Track which services are accounted for in groups
22
+ const groupedServiceIds = new Set();
23
+ // 1. Map option group and add-on breakdowns from priceBreakdown as service groups
24
+ const serviceGroups = [];
25
+ mapBreakdownGroups(offering, tier, priceBreakdown, currency, groupedServiceIds, serviceGroups);
26
+ // 3. Map remaining standalone services (not in any group or option group)
27
+ const standaloneServices = offering.services
28
+ .filter((s) => !groupedServiceIds.has(s.id))
29
+ .filter((svc) => {
30
+ const level = tier.serviceLevels.find((sl) => sl.serviceId === svc.id);
31
+ return (level &&
32
+ level.level !== "NOT_INCLUDED" &&
33
+ level.level !== "NOT_APPLICABLE");
34
+ })
35
+ .map((svc) => mapServiceToInput(svc, tier, currency, selectedBillingCycle));
36
+ // Calculate tier price
37
+ let tierPrice;
38
+ if (pricingMode === "CALCULATED") {
39
+ tierPrice = serviceGroups.reduce((sum, grp) => sum + (grp.recurringAmount ?? 0), 0);
40
+ }
41
+ else {
42
+ tierPrice =
43
+ priceBreakdown.tierCycleTotal ?? tier.pricing.amount ?? undefined;
44
+ }
15
45
  return {
16
46
  customerId: customerId ?? undefined,
17
47
  customerName: customerName ?? undefined,
@@ -24,6 +54,125 @@ export function mapOfferingToSubscription(options) {
24
54
  tierPricingMode: pricingMode,
25
55
  selectedBillingCycle,
26
56
  globalCurrency: currency,
57
+ autoRenew: true,
27
58
  createdAt,
59
+ services: standaloneServices,
60
+ serviceGroups,
61
+ };
62
+ }
63
+ /**
64
+ * Maps price breakdown option group and add-on breakdowns
65
+ * into subscription service groups.
66
+ */
67
+ function mapBreakdownGroups(offering, tier, breakdown, globalCurrency, groupedServiceIds, serviceGroups) {
68
+ // Non-add-on option groups (regular + setup)
69
+ const allOptionGroupBreakdowns = [
70
+ ...breakdown.optionGroupBreakdowns,
71
+ ...breakdown.setupGroupBreakdowns,
72
+ ];
73
+ for (const ogBreakdown of allOptionGroupBreakdowns) {
74
+ const og = offering.optionGroups.find((g) => g.id === ogBreakdown.optionGroupId);
75
+ if (!og || og.isAddOn)
76
+ continue;
77
+ const services = offering.services.filter((s) => s.optionGroupId === og.id);
78
+ if (services.length === 0)
79
+ continue;
80
+ services.forEach((s) => groupedServiceIds.add(s.id));
81
+ serviceGroups.push({
82
+ id: generateId(),
83
+ name: og.name,
84
+ optional: false,
85
+ costType: og.costType ?? undefined,
86
+ recurringAmount: ogBreakdown.recurringAmount || undefined,
87
+ recurringCurrency: ogBreakdown.currency || globalCurrency,
88
+ recurringBillingCycle: ogBreakdown.effectiveBillingCycle,
89
+ recurringDiscount: mapBreakdownDiscount(ogBreakdown.discount, og.discountMode === "INHERIT_TIER"
90
+ ? "TIER_INHERITED"
91
+ : "GROUP_INDEPENDENT"),
92
+ setupAmount: ogBreakdown.setupCost ?? undefined,
93
+ setupCurrency: ogBreakdown.setupCostCurrency ?? undefined,
94
+ services: services.map((svc) => mapServiceToInput(svc, tier, globalCurrency, ogBreakdown.effectiveBillingCycle)),
95
+ });
96
+ }
97
+ // Add-on option groups
98
+ for (const aoBreakdown of breakdown.addOnBreakdowns) {
99
+ const og = offering.optionGroups.find((g) => g.id === aoBreakdown.optionGroupId);
100
+ if (!og)
101
+ continue;
102
+ const services = offering.services.filter((s) => s.optionGroupId === og.id);
103
+ if (services.length === 0)
104
+ continue;
105
+ services.forEach((s) => groupedServiceIds.add(s.id));
106
+ serviceGroups.push({
107
+ id: generateId(),
108
+ name: og.name,
109
+ optional: true,
110
+ costType: og.costType ?? undefined,
111
+ recurringAmount: aoBreakdown.recurringAmount || undefined,
112
+ recurringCurrency: aoBreakdown.currency || globalCurrency,
113
+ recurringBillingCycle: aoBreakdown.selectedBillingCycle,
114
+ recurringDiscount: mapBreakdownDiscount(aoBreakdown.discount, og.discountMode === "INHERIT_TIER"
115
+ ? "TIER_INHERITED"
116
+ : "GROUP_INDEPENDENT"),
117
+ setupAmount: aoBreakdown.setupCost ?? undefined,
118
+ setupCurrency: aoBreakdown.setupCostCurrency ?? undefined,
119
+ services: services.map((svc) => mapServiceToInput(svc, tier, globalCurrency, aoBreakdown.selectedBillingCycle)),
120
+ });
121
+ }
122
+ }
123
+ /**
124
+ * Maps a single service from the offering to an InitializeServiceInput.
125
+ * Includes name, description, customValue from tier service levels,
126
+ * billing cycle, and usage metrics.
127
+ */
128
+ function mapServiceToInput(svc, tier, globalCurrency, billingCycle) {
129
+ const level = tier.serviceLevels.find((sl) => sl.serviceId === svc.id);
130
+ const metrics = mapUsageLimits(svc.id, tier.usageLimits, globalCurrency);
131
+ return {
132
+ id: generateId(),
133
+ name: svc.title,
134
+ description: svc.description ?? null,
135
+ customValue: level?.customValue ?? null,
136
+ recurringBillingCycle: billingCycle,
137
+ metrics,
138
+ };
139
+ }
140
+ /**
141
+ * Maps a resolved discount from the price breakdown to a DiscountInfoInitInput,
142
+ * or returns undefined if no discount.
143
+ */
144
+ function mapBreakdownDiscount(discount, source) {
145
+ if (!discount)
146
+ return undefined;
147
+ return {
148
+ originalAmount: discount.originalAmount,
149
+ discountType: discount.discountType,
150
+ discountValue: discount.discountValue,
151
+ source,
28
152
  };
29
153
  }
154
+ /**
155
+ * Maps usage limits from the tier to InitializeMetricInput for a given service.
156
+ */
157
+ function mapUsageLimits(serviceId, usageLimits, globalCurrency) {
158
+ const limits = usageLimits.filter((ul) => ul.serviceId === serviceId);
159
+ return limits.map((ul) => {
160
+ // Map SO's UsageResetCycle to SI's ResetPeriod (skip "NONE")
161
+ const usageResetPeriod = ul.resetCycle && ul.resetCycle !== "NONE"
162
+ ? ul.resetCycle
163
+ : undefined;
164
+ return {
165
+ id: generateId(),
166
+ name: ul.metric,
167
+ unitName: ul.unitName ?? "units",
168
+ limit: ul.freeLimit ?? ul.paidLimit ?? null,
169
+ freeLimit: ul.freeLimit ?? null,
170
+ paidLimit: ul.paidLimit ?? null,
171
+ currentUsage: 0,
172
+ usageResetPeriod,
173
+ unitCostAmount: ul.unitPrice ?? undefined,
174
+ unitCostCurrency: ul.unitPriceCurrency ?? globalCurrency,
175
+ unitCostBillingCycle: usageResetPeriod ? "MONTHLY" : undefined,
176
+ };
177
+ });
178
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "v6-service-offering",
2
+ "name": "@powerhousedao/service-offering",
3
3
  "description": "",
4
4
  "category": "",
5
5
  "publisher": {
@@ -28,8 +28,34 @@
28
28
  "name": "SubscriptionInstance"
29
29
  }
30
30
  ],
31
- "editors": [],
31
+ "editors": [
32
+ {
33
+ "id": "resource-instance-editor",
34
+ "name": "Resource Instance Editor",
35
+ "documentTypes": ["powerhouse/resource-instance"]
36
+ },
37
+ {
38
+ "id": "resource-template-editor",
39
+ "name": "Resource Template Editor",
40
+ "documentTypes": ["powerhouse/resource-template"]
41
+ },
42
+ {
43
+ "id": "service-offering-editor",
44
+ "name": "Service Offering Editor",
45
+ "documentTypes": ["powerhouse/service-offering"]
46
+ },
47
+ {
48
+ "id": "subscription-instance-editor",
49
+ "name": "Subscription Instance Editor",
50
+ "documentTypes": ["powerhouse/subscription-instance"]
51
+ }
52
+ ],
32
53
  "apps": [],
33
- "subgraphs": [],
54
+ "subgraphs": [
55
+ {
56
+ "id": "resources-services",
57
+ "name": "Resources & Services"
58
+ }
59
+ ],
34
60
  "importScripts": []
35
61
  }