bi-superpowers 1.0.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 (276) hide show
  1. package/.claude-plugin/marketplace.json +31 -0
  2. package/.claude-plugin/plugin.json +34 -0
  3. package/.claude-plugin/skill-manifest.json +79 -0
  4. package/.mcp.json +13 -0
  5. package/.plugin/plugin.json +14 -0
  6. package/LICENSE +21 -0
  7. package/README.md +849 -0
  8. package/bin/build-plugin.js +97 -0
  9. package/bin/cli.js +891 -0
  10. package/bin/commands/autoupdate.js +128 -0
  11. package/bin/commands/build-desktop.js +368 -0
  12. package/bin/commands/create-from-template.js +165 -0
  13. package/bin/commands/diff.js +435 -0
  14. package/bin/commands/install.js +542 -0
  15. package/bin/commands/lint.js +441 -0
  16. package/bin/commands/mcp-setup.js +255 -0
  17. package/bin/commands/session-update.js +204 -0
  18. package/bin/commands/smoke-test.js +20 -0
  19. package/bin/commands/uninstall.js +611 -0
  20. package/bin/commands/update-check.js +427 -0
  21. package/bin/commands/validate-cases.js +264 -0
  22. package/bin/commands/validate-projects.js +426 -0
  23. package/bin/commands/watch.js +251 -0
  24. package/bin/lib/agents.js +62 -0
  25. package/bin/lib/base-template-smoke.js +299 -0
  26. package/bin/lib/claude-hooks.js +160 -0
  27. package/bin/lib/generators/claude-plugin.js +529 -0
  28. package/bin/lib/generators/index.js +116 -0
  29. package/bin/lib/generators/shared.js +257 -0
  30. package/bin/lib/mcp-config.js +835 -0
  31. package/bin/lib/microsoft-mcp.js +206 -0
  32. package/bin/lib/powerbi-mcp-session.js +140 -0
  33. package/bin/lib/skills.js +164 -0
  34. package/bin/lib/template-scaffold.js +366 -0
  35. package/bin/mcp/powerbi-modeling-launcher.js +42 -0
  36. package/bin/postinstall.js +50 -0
  37. package/bin/utils/mcp-detect.js +346 -0
  38. package/bin/utils/tui.js +314 -0
  39. package/commands/bi-connect.md +520 -0
  40. package/commands/bi-dax.md +464 -0
  41. package/commands/bi-kickoff.md +550 -0
  42. package/commands/bi-modeling.md +485 -0
  43. package/commands/bi-performance.md +521 -0
  44. package/commands/bi-powerquery.md +229 -0
  45. package/commands/bi-refactor.md +249 -0
  46. package/commands/bi-scorecard.md +268 -0
  47. package/commands/bi-start.md +272 -0
  48. package/config.example.json +23 -0
  49. package/config.json +23 -0
  50. package/desktop-extension/manifest.json +30 -0
  51. package/desktop-extension/package.json +10 -0
  52. package/desktop-extension/server.js +137 -0
  53. package/package.json +94 -0
  54. package/skills/bi-connect/SKILL.md +522 -0
  55. package/skills/bi-connect/scripts/update-check.js +427 -0
  56. package/skills/bi-dax/SKILL.md +466 -0
  57. package/skills/bi-dax/scripts/update-check.js +427 -0
  58. package/skills/bi-kickoff/SKILL.md +552 -0
  59. package/skills/bi-kickoff/references/flow.html +78 -0
  60. package/skills/bi-kickoff/references/flow.md +62 -0
  61. package/skills/bi-kickoff/scripts/update-check.js +427 -0
  62. package/skills/bi-modeling/SKILL.md +487 -0
  63. package/skills/bi-modeling/scripts/update-check.js +427 -0
  64. package/skills/bi-performance/SKILL.md +523 -0
  65. package/skills/bi-performance/scripts/install-tabular-editor.ps1 +159 -0
  66. package/skills/bi-performance/scripts/run-bpa.ps1 +265 -0
  67. package/skills/bi-performance/scripts/update-check.js +427 -0
  68. package/skills/bi-powerquery/SKILL.md +231 -0
  69. package/skills/bi-powerquery/references/base-template-data-contract.md +323 -0
  70. package/skills/bi-powerquery/references/power-query-standards.md +74 -0
  71. package/skills/bi-powerquery/scripts/new-powerquery-staging.ps1 +371 -0
  72. package/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +225 -0
  73. package/skills/bi-powerquery/scripts/update-check.js +427 -0
  74. package/skills/bi-refactor/SKILL.md +251 -0
  75. package/skills/bi-refactor/references/flow.md +27 -0
  76. package/skills/bi-refactor/scripts/update-check.js +427 -0
  77. package/skills/bi-scorecard/SKILL.md +270 -0
  78. package/skills/bi-scorecard/examples/base-template-scorecard-overlay.json +82 -0
  79. package/skills/bi-scorecard/scripts/new-scorecard-blueprint-from-base-template.ps1 +124 -0
  80. package/skills/bi-scorecard/scripts/powerbi-goal-status-rules-api.ps1 +39 -0
  81. package/skills/bi-scorecard/scripts/powerbi-goal-values-api.ps1 +48 -0
  82. package/skills/bi-scorecard/scripts/powerbi-goals-api.ps1 +68 -0
  83. package/skills/bi-scorecard/scripts/powerbi-rest-common.ps1 +197 -0
  84. package/skills/bi-scorecard/scripts/powerbi-scorecards-api.ps1 +53 -0
  85. package/skills/bi-scorecard/scripts/update-check.js +427 -0
  86. package/skills/bi-start/SKILL.md +274 -0
  87. package/skills/bi-start/scripts/update-check.js +427 -0
  88. package/src/content/base.md +197 -0
  89. package/src/content/mcp-requirements.json +57 -0
  90. package/src/content/routing.md +201 -0
  91. package/src/content/skills/bi-connect.md +493 -0
  92. package/src/content/skills/bi-dax.md +437 -0
  93. package/src/content/skills/bi-kickoff/SKILL.md +523 -0
  94. package/src/content/skills/bi-kickoff/references/flow.html +78 -0
  95. package/src/content/skills/bi-kickoff/references/flow.md +62 -0
  96. package/src/content/skills/bi-modeling.md +458 -0
  97. package/src/content/skills/bi-performance/SKILL.md +494 -0
  98. package/src/content/skills/bi-performance/scripts/install-tabular-editor.ps1 +159 -0
  99. package/src/content/skills/bi-performance/scripts/run-bpa.ps1 +265 -0
  100. package/src/content/skills/bi-powerquery/SKILL.md +202 -0
  101. package/src/content/skills/bi-powerquery/references/base-template-data-contract.md +323 -0
  102. package/src/content/skills/bi-powerquery/references/power-query-standards.md +74 -0
  103. package/src/content/skills/bi-powerquery/scripts/new-powerquery-staging.ps1 +371 -0
  104. package/src/content/skills/bi-powerquery/scripts/test-powerquery-contract.ps1 +225 -0
  105. package/src/content/skills/bi-refactor/SKILL.md +222 -0
  106. package/src/content/skills/bi-refactor/references/flow.md +27 -0
  107. package/src/content/skills/bi-scorecard/SKILL.md +241 -0
  108. package/src/content/skills/bi-scorecard/examples/base-template-scorecard-blueprint.expected.json +105 -0
  109. package/src/content/skills/bi-scorecard/examples/base-template-scorecard-overlay.json +82 -0
  110. package/src/content/skills/bi-scorecard/scripts/new-scorecard-blueprint-from-base-template.ps1 +124 -0
  111. package/src/content/skills/bi-scorecard/scripts/powerbi-goal-status-rules-api.ps1 +39 -0
  112. package/src/content/skills/bi-scorecard/scripts/powerbi-goal-values-api.ps1 +48 -0
  113. package/src/content/skills/bi-scorecard/scripts/powerbi-goals-api.ps1 +68 -0
  114. package/src/content/skills/bi-scorecard/scripts/powerbi-rest-common.ps1 +197 -0
  115. package/src/content/skills/bi-scorecard/scripts/powerbi-scorecards-api.ps1 +53 -0
  116. package/src/content/skills/bi-start.md +266 -0
  117. package/templates/base-template/AGENTS.md +33 -0
  118. package/templates/base-template/base-template.Report/.platform +11 -0
  119. package/templates/base-template/base-template.Report/StaticResources/RegisteredResources/BISuperpowers.json +3888 -0
  120. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/CY18SU07.json +177 -0
  121. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BaseThemes/Fluent2-CY26SU03.json +4104 -0
  122. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleCityPark.json +26 -0
  123. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleDefault.json +26 -0
  124. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleNeutral.json +26 -0
  125. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleOrchid.json +26 -0
  126. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/AccessibleTidal.json +26 -0
  127. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Bloom.json +139 -0
  128. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CityPark.json +40 -0
  129. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Classroom.json +40 -0
  130. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/ColorblindSafe.json +48 -0
  131. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/CopilotDefault.json +1861 -0
  132. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Divergent.json +127 -0
  133. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Electric.json +48 -0
  134. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Frontier.json +136 -0
  135. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/HighContrast.json +40 -0
  136. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Highrise.json +41 -0
  137. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Innovate.json +227 -0
  138. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/NewExecutive.json +41 -0
  139. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Solar.json +33 -0
  140. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Storm.json +25 -0
  141. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Sunset.json +48 -0
  142. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Temperature.json +33 -0
  143. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Tidal.json +100 -0
  144. package/templates/base-template/base-template.Report/StaticResources/SharedResources/BuiltInThemes/Twilight.json +40 -0
  145. package/templates/base-template/base-template.Report/definition/bookmarks/1d40d43c7ade66e8603c.bookmark.json +2297 -0
  146. package/templates/base-template/base-template.Report/definition/bookmarks/af068ff51c0ca3089ea7.bookmark.json +2300 -0
  147. package/templates/base-template/base-template.Report/definition/bookmarks/bookmarks.json +11 -0
  148. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/page.json +130 -0
  149. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/mobile.json +11 -0
  150. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/visual.json +669 -0
  151. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/mobile.json +11 -0
  152. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/visual.json +723 -0
  153. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/mobile.json +11 -0
  154. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/visual.json +333 -0
  155. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/mobile.json +11 -0
  156. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/visual.json +109 -0
  157. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/mobile.json +31 -0
  158. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/55e10ac7d76a1954f94f/visual.json +378 -0
  159. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/mobile.json +11 -0
  160. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/57f52ecf4490f70e4da1/visual.json +175 -0
  161. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/mobile.json +11 -0
  162. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/visual.json +468 -0
  163. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/mobile.json +11 -0
  164. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/visual.json +359 -0
  165. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/mobile.json +11 -0
  166. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/visual.json +690 -0
  167. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/90677f13cea5d1275990/visual.json +17 -0
  168. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/mobile.json +11 -0
  169. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/visual.json +468 -0
  170. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/mobile.json +10 -0
  171. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/9fe17b1971f68443fc15/visual.json +328 -0
  172. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/mobile.json +11 -0
  173. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/visual.json +578 -0
  174. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/mobile.json +11 -0
  175. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/visual.json +432 -0
  176. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/mobile.json +11 -0
  177. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/visual.json +801 -0
  178. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/mobile.json +37 -0
  179. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/visual.json +1318 -0
  180. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/b529688fe5a226643322/visual.json +209 -0
  181. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/mobile.json +11 -0
  182. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/c4c6f332d05e72e2eb06/visual.json +174 -0
  183. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/mobile.json +29 -0
  184. package/templates/base-template/base-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/visual.json +241 -0
  185. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/page.json +130 -0
  186. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/mobile.json +11 -0
  187. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/07e9c4302e29029c5462/visual.json +690 -0
  188. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/mobile.json +11 -0
  189. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/109ceede4bc015b0c006/visual.json +468 -0
  190. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/mobile.json +11 -0
  191. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/118257e006d472277e10/visual.json +359 -0
  192. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/mobile.json +11 -0
  193. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/2caf02e0137c4a1280cc/visual.json +669 -0
  194. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/mobile.json +11 -0
  195. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/311e76fe3c9edad68204/visual.json +109 -0
  196. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/31c21f8cbeb3b208940a/visual.json +209 -0
  197. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/3ab72c25062437149b03/visual.json +17 -0
  198. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/mobile.json +11 -0
  199. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5959867442abcb0ce2b3/visual.json +788 -0
  200. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/mobile.json +11 -0
  201. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/5b96e0f88d192b044a13/visual.json +592 -0
  202. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/mobile.json +11 -0
  203. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/64e749a63d0786000e22/visual.json +468 -0
  204. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/mobile.json +11 -0
  205. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/7ae1ca604edac6586ad0/visual.json +1310 -0
  206. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/mobile.json +11 -0
  207. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/840300733885141a6603/visual.json +175 -0
  208. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/mobile.json +11 -0
  209. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/a38448cdb203279273d2/visual.json +516 -0
  210. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d1e86f213a3841d12e20/visual.json +328 -0
  211. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/mobile.json +11 -0
  212. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d4a484c1bcc8ee3075e2/visual.json +432 -0
  213. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/mobile.json +11 -0
  214. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/d87cb5cf06acca19bbb5/visual.json +241 -0
  215. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/mobile.json +11 -0
  216. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/e243da2677209ed69408/visual.json +174 -0
  217. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/mobile.json +11 -0
  218. package/templates/base-template/base-template.Report/definition/pages/9a5b670b015cab882629/visuals/f3aaf24f5b22b67573b0/visual.json +333 -0
  219. package/templates/base-template/base-template.Report/definition/pages/pages.json +8 -0
  220. package/templates/base-template/base-template.Report/definition/report.json +89 -0
  221. package/templates/base-template/base-template.Report/definition/version.json +4 -0
  222. package/templates/base-template/base-template.Report/definition.pbir +9 -0
  223. package/templates/base-template/base-template.SemanticModel/.platform +11 -0
  224. package/templates/base-template/base-template.SemanticModel/definition/cultures/es-AR.tmdl +11185 -0
  225. package/templates/base-template/base-template.SemanticModel/definition/database.tmdl +3 -0
  226. package/templates/base-template/base-template.SemanticModel/definition/expressions.tmdl +234 -0
  227. package/templates/base-template/base-template.SemanticModel/definition/functions.tmdl +637 -0
  228. package/templates/base-template/base-template.SemanticModel/definition/model.tmdl +82 -0
  229. package/templates/base-template/base-template.SemanticModel/definition/relationships.tmdl +271 -0
  230. package/templates/base-template/base-template.SemanticModel/definition/tables/Calendario.tmdl +200 -0
  231. package/templates/base-template/base-template.SemanticModel/definition/tables/Campa/303/261as.tmdl +75 -0
  232. package/templates/base-template/base-template.SemanticModel/definition/tables/Canales.tmdl +84 -0
  233. package/templates/base-template/base-template.SemanticModel/definition/tables/Clientes.tmdl +143 -0
  234. package/templates/base-template/base-template.SemanticModel/definition/tables/Devoluciones.tmdl +95 -0
  235. package/templates/base-template/base-template.SemanticModel/definition/tables/Ejecuci/303/263n proyectos.tmdl" +130 -0
  236. package/templates/base-template/base-template.SemanticModel/definition/tables/Entregas.tmdl +122 -0
  237. package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos m/303/251tricas.tmdl" +40 -0
  238. package/templates/base-template/base-template.SemanticModel/definition/tables/Equipos.tmdl +73 -0
  239. package/templates/base-template/base-template.SemanticModel/definition/tables/Horas.tmdl +122 -0
  240. package/templates/base-template/base-template.SemanticModel/definition/tables/Interacciones clientes.tmdl +146 -0
  241. package/templates/base-template/base-template.SemanticModel/definition/tables/Leads.tmdl +119 -0
  242. package/templates/base-template/base-template.SemanticModel/definition/tables/Monedas.tmdl +44 -0
  243. package/templates/base-template/base-template.SemanticModel/definition/tables/Movimientos financieros.tmdl +145 -0
  244. package/templates/base-template/base-template.SemanticModel/definition/tables/M/303/251tricas.tmdl +1294 -0
  245. package/templates/base-template/base-template.SemanticModel/definition/tables/N/303/263mina.tmdl +110 -0
  246. package/templates/base-template/base-template.SemanticModel/definition/tables/Oportunidades.tmdl +135 -0
  247. package/templates/base-template/base-template.SemanticModel/definition/tables/Presupuesto.tmdl +125 -0
  248. package/templates/base-template/base-template.SemanticModel/definition/tables/Productos.tmdl +98 -0
  249. package/templates/base-template/base-template.SemanticModel/definition/tables/Proyectos.tmdl +77 -0
  250. package/templates/base-template/base-template.SemanticModel/definition/tables/Servicios.tmdl +75 -0
  251. package/templates/base-template/base-template.SemanticModel/definition/tables/Tareas proyecto.tmdl +102 -0
  252. package/templates/base-template/base-template.SemanticModel/definition/tables/Tipo de cambio.tmdl +67 -0
  253. package/templates/base-template/base-template.SemanticModel/definition/tables/Ventas.tmdl +180 -0
  254. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux An/303/241lisis dimensiones.tmdl" +38 -0
  255. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Comparaciones.tmdl +227 -0
  256. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Compatibilidad m/303/251trica-dimensi/303/263n.tmdl" +68 -0
  257. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modelo configuraci/303/263n.tmdl" +44 -0
  258. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Modo fechas.tmdl +36 -0
  259. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux M/303/251trica-Equipo.tmdl" +102 -0
  260. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Overrides m/303/251trica-dimensi/303/263n.tmdl" +54 -0
  261. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Per/303/255odos.tmdl" +182 -0
  262. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas modo.tmdl +36 -0
  263. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Rango fechas.tmdl +27 -0
  264. package/templates/base-template/base-template.SemanticModel/definition/tables/_Aux Vista de calendario.tmdl +30 -0
  265. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC C/303/241lculo.tmdl" +70 -0
  266. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Eje X.tmdl +63 -0
  267. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC M/303/251trica.tmdl" +374 -0
  268. package/templates/base-template/base-template.SemanticModel/definition/tables/_GC Tipo c/303/241lculo.tmdl" +223 -0
  269. package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Dimensi/303/263n.tmdl" +98 -0
  270. package/templates/base-template/base-template.SemanticModel/definition/tables/_PC Eje X.tmdl +68 -0
  271. package/templates/base-template/base-template.SemanticModel/definition/tables//303/223rdenes servicio.tmdl" +151 -0
  272. package/templates/base-template/base-template.SemanticModel/definition.pbism +5 -0
  273. package/templates/base-template/base-template.SemanticModel/diagramLayout.json +568 -0
  274. package/templates/base-template/base-template.pbip +14 -0
  275. package/templates/base-template/template.manifest.json +41 -0
  276. package/theme/BISuperpowers.json +3888 -0
@@ -0,0 +1,637 @@
1
+ /// Devuelve el tipo de cambio de una moneda hacia la moneda base definida por MonedaBase para una fecha; la moneda base devuelve 1 sin depender de la tabla de tasas.
2
+ function GetExchangeRate =
3
+ ( currency : STRING, rateDate : DATETIME ) =>
4
+ // Esta funcion recibe una moneda y una fecha, y devuelve la tasa hacia la moneda base.
5
+ // currency es el codigo de moneda que llega desde la fila o medida, por ejemplo USD o EUR.
6
+ // rateDate es la fecha para buscar la tasa; si viene vacia, usamos la ultima fecha disponible.
7
+ VAR __BaseCurrency =
8
+ // COALESCE devuelve el primer valor que no sea BLANK; si no encuentra nada, usa USD.
9
+ COALESCE (
10
+ // MAXX recorre una tabla fila por fila y devuelve el valor maximo encontrado.
11
+ MAXX (
12
+ // FILTER deja pasar solo la fila donde Configuracion dice Moneda Base.
13
+ FILTER (
14
+ '_Aux Modelo configuración',
15
+ '_Aux Modelo configuración'[Configuración] = "Moneda Base"
16
+ ),
17
+ // De esa fila tomamos el texto de la moneda base.
18
+ '_Aux Modelo configuración'[ValorTexto]
19
+ ),
20
+ // USD es el valor de seguridad si la tabla de configuracion no trae moneda base.
21
+ "USD"
22
+ )
23
+ VAR __Currency =
24
+ // Si la moneda pedida viene vacia, asumimos que ya es la moneda base.
25
+ COALESCE ( currency, __BaseCurrency )
26
+ VAR __SafeDate =
27
+ // IF elige entre dos caminos: cuando rateDate esta vacia o cuando tiene fecha.
28
+ IF (
29
+ // ISBLANK detecta valores vacios en DAX.
30
+ ISBLANK ( rateDate ),
31
+ // Si no hay fecha, buscamos la ultima fecha cargada en Tipo de cambio.
32
+ CALCULATE (
33
+ MAX ( 'Tipo de cambio'[Fecha] ),
34
+ // REMOVEFILTERS ignora filtros externos para mirar toda la tabla de tasas.
35
+ REMOVEFILTERS ( 'Tipo de cambio' )
36
+ ),
37
+ // Si rateDate tiene valor, usamos esa fecha directamente.
38
+ rateDate
39
+ )
40
+ RETURN
41
+ // RETURN indica cual es el resultado final de la funcion.
42
+ IF (
43
+ // Si la moneda pedida es la moneda base, la tasa es 1 porque no hay conversion.
44
+ __Currency = __BaseCurrency,
45
+ 1,
46
+ // Si no es moneda base, buscamos la fecha de tasa mas reciente hasta __SafeDate.
47
+ VAR __LastAvailableDate =
48
+ CALCULATE (
49
+ MAX ( 'Tipo de cambio'[Fecha] ),
50
+ REMOVEFILTERS ( 'Tipo de cambio' ),
51
+ 'Tipo de cambio'[Moneda] = __Currency,
52
+ 'Tipo de cambio'[Fecha] <= __SafeDate
53
+ )
54
+ VAR __Rate =
55
+ // Con la fecha encontrada, ahora buscamos el valor de la tasa.
56
+ CALCULATE (
57
+ MAX ( 'Tipo de cambio'[TipoCambioBase] ),
58
+ REMOVEFILTERS ( 'Tipo de cambio' ),
59
+ 'Tipo de cambio'[Moneda] = __Currency,
60
+ 'Tipo de cambio'[Fecha] = __LastAvailableDate
61
+ )
62
+ RETURN
63
+ // Si falta la tasa, devolvemos 1 para que el reporte no explote con error.
64
+ COALESCE ( __Rate, 1 )
65
+ )
66
+ lineageTag: eaeb396c-d336-4383-9809-420213485325
67
+
68
+ /// Convierte un importe desde una moneda origen hacia una moneda destino usando la moneda base definida por MonedaBase como pivote.
69
+ function ConvertCurrency =
70
+ ( amount : NUMERIC, fromCurrency : STRING, toCurrency : STRING, rateDate : DATETIME ) =>
71
+ // Esta funcion convierte un importe desde una moneda origen hacia una moneda destino.
72
+ // amount es el valor numerico que queremos convertir.
73
+ // fromCurrency es la moneda original del importe.
74
+ // toCurrency es la moneda final que el usuario quiere ver.
75
+ // rateDate es la fecha usada para buscar la tasa de cambio.
76
+ IF (
77
+ // Si no hay importe, devolvemos BLANK para que el visual muestre vacio y no cero falso.
78
+ ISBLANK ( amount ),
79
+ BLANK (),
80
+ // Si hay importe, calculamos las monedas y las tasas necesarias.
81
+ VAR __BaseCurrency =
82
+ // Buscamos la moneda base del modelo; si falta, usamos USD.
83
+ COALESCE (
84
+ MAXX (
85
+ FILTER (
86
+ '_Aux Modelo configuración',
87
+ '_Aux Modelo configuración'[Configuración] = "Moneda Base"
88
+ ),
89
+ '_Aux Modelo configuración'[ValorTexto]
90
+ ),
91
+ "USD"
92
+ )
93
+ VAR __FromCurrency =
94
+ // Si la moneda origen viene vacia, asumimos moneda base.
95
+ COALESCE ( fromCurrency, __BaseCurrency )
96
+ VAR __ToCurrency =
97
+ // Si la moneda destino viene vacia, asumimos moneda base.
98
+ COALESCE ( toCurrency, __BaseCurrency )
99
+ RETURN
100
+ IF (
101
+ // Si origen y destino son iguales, no hace falta convertir.
102
+ __FromCurrency = __ToCurrency,
103
+ amount,
104
+ // Tasa desde la moneda origen hacia la moneda base.
105
+ VAR __RateToBase = GetExchangeRate ( __FromCurrency, rateDate )
106
+ // Tasa desde la moneda destino hacia la moneda base.
107
+ VAR __RateFromBase = GetExchangeRate ( __ToCurrency, rateDate )
108
+ RETURN
109
+ // Primero llevamos el importe a moneda base y luego a moneda destino.
110
+ DIVIDE ( amount, __RateToBase ) * __RateFromBase
111
+ )
112
+ )
113
+ lineageTag: 6015e897-8732-43b5-ba6f-46d586d5ce00
114
+
115
+ /// Devuelve el año fiscal semanal aproximado 4-4-5 para una fecha. Sirve para comparar calendarios de retail contra calendario gregoriano.
116
+ function Calendar445Year =
117
+ ( DateValue : DATETIME ) =>
118
+ // Esta funcion recibe una fecha y calcula a que año fiscal 4-4-5 pertenece.
119
+ VAR __Date =
120
+ // Guardamos la fecha de entrada en una variable para que el resto sea mas legible.
121
+ DateValue
122
+ VAR __FiscalAnchorDate =
123
+ // WEEKDAY con 2 significa que la semana empieza el lunes.
124
+ // Restamos el numero de dia de la semana y sumamos 4 para movernos al jueves.
125
+ // Usar el jueves estabiliza semanas que cruzan entre dos años.
126
+ __Date - WEEKDAY ( __Date, 2 ) + 4
127
+ RETURN
128
+ // Si la fecha esta vacia, devolvemos BLANK; si no, devolvemos el año del jueves calculado.
129
+ IF ( ISBLANK ( __Date ), BLANK (), YEAR ( __FiscalAnchorDate ) )
130
+ lineageTag: 66eb01d4-c444-474f-8d1b-b3da5cb58aa5
131
+
132
+ /// Devuelve el mes fiscal aproximado de un calendario semanal 4-4-5 para una fecha. Es una aproximación didáctica para el template.
133
+ function Calendar445MonthNr =
134
+ ( DateValue : DATETIME ) =>
135
+ // Esta funcion convierte una fecha en numero de mes fiscal 4-4-5 aproximado.
136
+ VAR __Date =
137
+ // Guardamos la fecha de entrada para reutilizarla sin repetir el parametro.
138
+ DateValue
139
+ VAR __WeekNr =
140
+ // WEEKNUM con 21 calcula la semana ISO, que usa lunes como inicio de semana.
141
+ WEEKNUM ( __Date, 21 )
142
+ VAR __FiscalMonth =
143
+ // SWITCH TRUE evalua condiciones en orden y devuelve el primer resultado que coincida.
144
+ SWITCH (
145
+ TRUE (),
146
+ // Semanas 1 a 4 forman el primer mes fiscal.
147
+ __WeekNr <= 4, 1,
148
+ // Semanas 5 a 8 forman el segundo mes fiscal.
149
+ __WeekNr <= 8, 2,
150
+ // Semanas 9 a 13 forman el tercer mes fiscal, cerrando el patron 4-4-5.
151
+ __WeekNr <= 13, 3,
152
+ __WeekNr <= 17, 4,
153
+ __WeekNr <= 21, 5,
154
+ __WeekNr <= 26, 6,
155
+ __WeekNr <= 30, 7,
156
+ __WeekNr <= 34, 8,
157
+ __WeekNr <= 39, 9,
158
+ __WeekNr <= 43, 10,
159
+ __WeekNr <= 47, 11,
160
+ // Cualquier semana posterior queda en el mes fiscal 12.
161
+ 12
162
+ )
163
+ RETURN
164
+ // Si la fecha esta vacia, devolvemos BLANK; si no, devolvemos el mes fiscal.
165
+ IF ( ISBLANK ( __Date ), BLANK (), __FiscalMonth )
166
+ lineageTag: af2ea27b-986e-4cb6-ac7a-fa8721391ea6
167
+
168
+ /// Devuelve una tabla de una fila con el calendario elegido, el rango actual y el rango previo. En modo predefinido toma el rango actual desde _Aux Períodos y calcula el previo en DAX; en modo Rango fechas usa las tablas auxiliares desconectadas.
169
+ function CalendarContext =
170
+ () =>
171
+ // Esta funcion no recibe parametros: lee los slicers activos del reporte.
172
+ VAR __CalendarType =
173
+ // Vista temporal activa: calendario gregoriano o semanal 4-4-5.
174
+ SELECTEDVALUE ( '_Aux Vista de calendario'[Vista de calendario], "Gregoriano" )
175
+ VAR __Mode =
176
+ // Modo semantico oculto: Predefinido usa Aux Comparaciones; Rango fechas usa el slicer desconectado.
177
+ SELECTEDVALUE ( '_Aux Modo fechas'[Modo fechas], "Predefinido" )
178
+ VAR __Comparison =
179
+ // Comparacion elegida en el slicer predefinido, por ejemplo Este mes vs mes pasado.
180
+ SELECTEDVALUE ( '_Aux Comparaciones'[Comparación] )
181
+ VAR __DefaultComparison =
182
+ // Si no hay seleccion predefinida, usamos Este mes para el calendario activo.
183
+ MAXX (
184
+ FILTER (
185
+ ALL ( '_Aux Comparaciones' ),
186
+ '_Aux Comparaciones'[Vista de calendario] = __CalendarType
187
+ && '_Aux Comparaciones'[Orden] = 10
188
+ ),
189
+ '_Aux Comparaciones'[Comparación]
190
+ )
191
+ VAR __SelectedComparison =
192
+ // COALESCE toma la seleccion del usuario; si esta vacia, toma el default.
193
+ COALESCE ( __Comparison, __DefaultComparison )
194
+ VAR __SelectedSort =
195
+ // Orden numerico de la comparacion activa; si algo falla, vuelve a Este mes.
196
+ COALESCE (
197
+ MAXX (
198
+ FILTER (
199
+ ALL ( '_Aux Comparaciones' ),
200
+ '_Aux Comparaciones'[Vista de calendario] = __CalendarType
201
+ && '_Aux Comparaciones'[Comparación] = __SelectedComparison
202
+ ),
203
+ '_Aux Comparaciones'[Orden]
204
+ ),
205
+ 10
206
+ )
207
+ VAR __CurrentRows =
208
+ // Buscamos el rango actual en Aux Periodos, que es la tabla fuente confiable de fechas.
209
+ FILTER (
210
+ ALL ( '_Aux Períodos' ),
211
+ '_Aux Períodos'[Vista de calendario] = __CalendarType
212
+ && '_Aux Períodos'[Orden] = __SelectedSort
213
+ )
214
+ VAR __CurrentStart =
215
+ // Fecha inicial del periodo actual predefinido.
216
+ MINX ( __CurrentRows, '_Aux Períodos'[FechaInicio] )
217
+ VAR __CurrentEnd =
218
+ // Fecha final del periodo actual predefinido.
219
+ MAXX ( __CurrentRows, '_Aux Períodos'[FechaFin] )
220
+ VAR __Days =
221
+ // Cantidad de dias del periodo actual, contando inicio y fin.
222
+ IF ( ISBLANK ( __CurrentStart ) || ISBLANK ( __CurrentEnd ), BLANK (), DATEDIFF ( __CurrentStart, __CurrentEnd, DAY ) + 1 )
223
+ VAR __OffsetDays =
224
+ // Dias transcurridos dentro del periodo actual; sirve para cortar periodos previos incompletos.
225
+ IF ( ISBLANK ( __CurrentStart ) || ISBLANK ( __CurrentEnd ), BLANK (), DATEDIFF ( __CurrentStart, __CurrentEnd, DAY ) )
226
+ VAR __PriorSort =
227
+ // Para periodos en curso, el periodo previo sale de otra fila de Aux Periodos.
228
+ SWITCH (
229
+ TRUE (),
230
+ __SelectedSort = 8, 9,
231
+ __SelectedSort = 10, 11,
232
+ __SelectedSort = 12, 13,
233
+ __SelectedSort = 14, 15,
234
+ __SelectedSort = 16, 17,
235
+ BLANK ()
236
+ )
237
+ VAR __PriorRows =
238
+ // Fila del periodo previo fijo, por ejemplo Mes pasado para Este mes.
239
+ FILTER (
240
+ ALL ( '_Aux Períodos' ),
241
+ '_Aux Períodos'[Vista de calendario] = __CalendarType
242
+ && '_Aux Períodos'[Orden] = __PriorSort
243
+ )
244
+ VAR __PriorStart =
245
+ // Inicio completo del periodo previo fijo.
246
+ MINX ( __PriorRows, '_Aux Períodos'[FechaInicio] )
247
+ VAR __PriorEndFull =
248
+ // Fin completo del periodo previo fijo.
249
+ MAXX ( __PriorRows, '_Aux Períodos'[FechaFin] )
250
+ VAR __PriorEndCut =
251
+ // Si el periodo actual esta incompleto, cortamos el previo en la misma posicion relativa.
252
+ IF (
253
+ ISBLANK ( __PriorStart ) || ISBLANK ( __PriorEndFull ) || ISBLANK ( __OffsetDays ),
254
+ BLANK (),
255
+ MIN ( __PriorEndFull, __PriorStart + __OffsetDays )
256
+ )
257
+ VAR __Is445 =
258
+ // TRUE cuando el calendario activo es el semanal 4-4-5.
259
+ __CalendarType = "Semanal 4-4-5"
260
+ VAR __FiscalMonthKey =
261
+ // Clave fiscal del mes que contiene el inicio actual.
262
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fecha] = __CurrentStart ), Calendario[Fiscal445MonthKey] )
263
+ VAR __PrevFiscalMonthKey =
264
+ // Mes fiscal inmediatamente anterior al mes actual.
265
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445MonthKey] < __FiscalMonthKey ), Calendario[Fiscal445MonthKey] )
266
+ VAR __FiscalQuarterKey =
267
+ // Clave fiscal del trimestre que contiene el inicio actual.
268
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fecha] = __CurrentStart ), Calendario[Fiscal445QuarterKey] )
269
+ VAR __PrevFiscalQuarterKey =
270
+ // Trimestre fiscal inmediatamente anterior al trimestre actual.
271
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445QuarterKey] < __FiscalQuarterKey ), Calendario[Fiscal445QuarterKey] )
272
+ VAR __FiscalSemesterKey =
273
+ // Clave fiscal del semestre que contiene el inicio actual.
274
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fecha] = __CurrentStart ), Calendario[Fiscal445SemesterKey] )
275
+ VAR __PrevFiscalSemesterKey =
276
+ // Semestre fiscal inmediatamente anterior al semestre actual.
277
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445SemesterKey] < __FiscalSemesterKey ), Calendario[Fiscal445SemesterKey] )
278
+ VAR __FiscalYear =
279
+ // Año fiscal que contiene el inicio actual.
280
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fecha] = __CurrentStart ), Calendario[Fiscal445Year] )
281
+ VAR __PrevFiscalYear =
282
+ // Año fiscal inmediatamente anterior al actual.
283
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445Year] < __FiscalYear ), Calendario[Fiscal445Year] )
284
+ VAR __PrevMonthStart =
285
+ // Inicio del mes previo para comparaciones de Mes pasado.
286
+ IF (
287
+ __Is445,
288
+ MINX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445MonthKey] = __PrevFiscalMonthKey ), Calendario[Fecha] ),
289
+ EOMONTH ( __CurrentStart, -2 ) + 1
290
+ )
291
+ VAR __PrevMonthEnd =
292
+ // Fin del mes previo para comparaciones de Mes pasado.
293
+ IF (
294
+ __Is445,
295
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445MonthKey] = __PrevFiscalMonthKey ), Calendario[Fecha] ),
296
+ EOMONTH ( __CurrentStart, -1 )
297
+ )
298
+ VAR __PrevQuarterStart =
299
+ // Inicio del trimestre previo para comparaciones de Trimestre pasado.
300
+ IF (
301
+ __Is445,
302
+ MINX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445QuarterKey] = __PrevFiscalQuarterKey ), Calendario[Fecha] ),
303
+ EDATE ( __CurrentStart, -3 )
304
+ )
305
+ VAR __PrevQuarterEnd =
306
+ // Fin del trimestre previo para comparaciones de Trimestre pasado.
307
+ IF (
308
+ __Is445,
309
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445QuarterKey] = __PrevFiscalQuarterKey ), Calendario[Fecha] ),
310
+ __CurrentStart - 1
311
+ )
312
+ VAR __PrevSemesterStart =
313
+ // Inicio del semestre previo para comparaciones de Semestre pasado.
314
+ IF (
315
+ __Is445,
316
+ MINX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445SemesterKey] = __PrevFiscalSemesterKey ), Calendario[Fecha] ),
317
+ EDATE ( __CurrentStart, -6 )
318
+ )
319
+ VAR __PrevSemesterEnd =
320
+ // Fin del semestre previo para comparaciones de Semestre pasado.
321
+ IF (
322
+ __Is445,
323
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445SemesterKey] = __PrevFiscalSemesterKey ), Calendario[Fecha] ),
324
+ __CurrentStart - 1
325
+ )
326
+ VAR __PrevYearStart =
327
+ // Inicio del año previo para comparaciones de Año pasado.
328
+ IF (
329
+ __Is445,
330
+ MINX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445Year] = __PrevFiscalYear ), Calendario[Fecha] ),
331
+ DATE ( YEAR ( __CurrentStart ) - 1, 1, 1 )
332
+ )
333
+ VAR __PrevYearEnd =
334
+ // Fin del año previo para comparaciones de Año pasado.
335
+ IF (
336
+ __Is445,
337
+ MAXX ( FILTER ( ALL ( Calendario ), Calendario[Fiscal445Year] = __PrevFiscalYear ), Calendario[Fecha] ),
338
+ DATE ( YEAR ( __CurrentStart ) - 1, 12, 31 )
339
+ )
340
+ VAR __PreviousStart =
341
+ // Regla de inicio del periodo previo segun la opcion activa.
342
+ SWITCH (
343
+ TRUE (),
344
+ ISBLANK ( __CurrentStart ) || ISBLANK ( __CurrentEnd ), BLANK (),
345
+ __SelectedSort IN { 1, 2 }, __CurrentStart - 1,
346
+ __SelectedSort IN { 3, 4, 5, 6, 7 }, __CurrentStart - __Days,
347
+ __SelectedSort IN { 8, 10, 12, 14, 16 }, __PriorStart,
348
+ __SelectedSort = 9, __CurrentStart - 7,
349
+ __SelectedSort = 11, __PrevMonthStart,
350
+ __SelectedSort = 13, __PrevQuarterStart,
351
+ __SelectedSort = 15, __PrevSemesterStart,
352
+ __SelectedSort = 17, __PrevYearStart,
353
+ BLANK ()
354
+ )
355
+ VAR __PreviousEnd =
356
+ // Regla de fin del periodo previo segun la opcion activa.
357
+ SWITCH (
358
+ TRUE (),
359
+ ISBLANK ( __CurrentStart ) || ISBLANK ( __CurrentEnd ), BLANK (),
360
+ __SelectedSort IN { 1, 2 }, __CurrentEnd - 1,
361
+ __SelectedSort IN { 3, 4, 5, 6, 7 }, __CurrentStart - 1,
362
+ __SelectedSort IN { 8, 10, 12, 14, 16 }, __PriorEndCut,
363
+ __SelectedSort = 9, __CurrentEnd - 7,
364
+ __SelectedSort = 11, __PrevMonthEnd,
365
+ __SelectedSort = 13, __PrevQuarterEnd,
366
+ __SelectedSort = 15, __PrevSemesterEnd,
367
+ __SelectedSort = 17, __PrevYearEnd,
368
+ BLANK ()
369
+ )
370
+ VAR __PresetContext =
371
+ // Normalizamos el modo predefinido al contrato comun de CalendarContext.
372
+ ROW (
373
+ "Calendar Type", __CalendarType,
374
+ "Current Start", __CurrentStart,
375
+ "Current End", __CurrentEnd,
376
+ "Previous Start", __PreviousStart,
377
+ "Previous End", __PreviousEnd
378
+ )
379
+ VAR __HasCustomRange =
380
+ // TRUE solo cuando el slicer de rango tiene un filtro real aplicado.
381
+ ISFILTERED ( '_Aux Rango fechas'[Fecha] )
382
+ VAR __UseCustomRange =
383
+ __Mode = "Rango fechas" && __HasCustomRange
384
+ VAR __CustomMode =
385
+ // Si el usuario no eligio modo, comparamos contra el periodo inmediatamente previo.
386
+ SELECTEDVALUE ( '_Aux Rango fechas modo'[Rango fechas modo], "Periodo previo" )
387
+ VAR __SelectedCustomDates =
388
+ // ALLSELECTED conserva el rango visible seleccionado por el slicer desconectado.
389
+ ALLSELECTED ( '_Aux Rango fechas'[Fecha] )
390
+ VAR __CustomStart =
391
+ // Fecha inicial del rango personalizado.
392
+ MINX ( __SelectedCustomDates, '_Aux Rango fechas'[Fecha] )
393
+ VAR __CustomEnd =
394
+ // Fecha final del rango personalizado.
395
+ MAXX ( __SelectedCustomDates, '_Aux Rango fechas'[Fecha] )
396
+ VAR __SpanDays =
397
+ // Cantidad de dias del rango, inclusiva: inicio y fin cuentan.
398
+ DATEDIFF ( __CustomStart, __CustomEnd, DAY ) + 1
399
+ VAR __CustomPreviousStart =
400
+ // Interanual desplaza 12 meses; Periodo previo toma la misma duracion justo antes del inicio.
401
+ SWITCH (
402
+ TRUE (),
403
+ NOT __UseCustomRange, BLANK (),
404
+ __CustomMode = "Interanual", EDATE ( __CustomStart, -12 ),
405
+ __CustomStart - __SpanDays
406
+ )
407
+ VAR __CustomPreviousEnd =
408
+ // El fin previo acompaña la misma regla que el inicio previo.
409
+ SWITCH (
410
+ TRUE (),
411
+ NOT __UseCustomRange, BLANK (),
412
+ __CustomMode = "Interanual", EDATE ( __CustomEnd, -12 ),
413
+ __CustomStart - 1
414
+ )
415
+ VAR __CustomContext =
416
+ // Normalizamos el modo personalizado al mismo contrato que el modo predefinido.
417
+ ROW (
418
+ "Calendar Type", __CalendarType,
419
+ "Current Start", __CustomStart,
420
+ "Current End", __CustomEnd,
421
+ "Previous Start", __CustomPreviousStart,
422
+ "Previous End", __CustomPreviousEnd
423
+ )
424
+ RETURN
425
+ // Devolvemos una sola fila: preset cuando no aplica rango, custom cuando aplica rango.
426
+ UNION (
427
+ FILTER ( __PresetContext, NOT __UseCustomRange ),
428
+ FILTER ( __CustomContext, __UseCustomRange )
429
+ )
430
+ lineageTag: 411b9c02-2219-4344-9f91-224e5e3f6185
431
+
432
+ /// Devuelve el formato de la métrica seleccionada usando el símbolo visible de Monedas[Símbolo] cuando la métrica es monetaria.
433
+ function FormatoMetricaSeleccionada =
434
+ () =>
435
+ // Esta funcion devuelve un texto de formato para la metrica elegida en el slicer.
436
+ VAR __MetricFormat =
437
+ // Leemos el formato base guardado en la tabla Metricas, por ejemplo #,0 o 0.0%.
438
+ SELECTEDVALUE ( 'Métricas'[Formato] )
439
+ VAR __CurrencySymbol =
440
+ // Leemos el simbolo de moneda seleccionado, por ejemplo $, EUR o USD.
441
+ SELECTEDVALUE ( Monedas[Símbolo] )
442
+ VAR __Monetary =
443
+ // Esta bandera indica si la metrica debe mostrarse como moneda.
444
+ SELECTEDVALUE ( 'Métricas'[Monetaria] )
445
+ RETURN
446
+ // SWITCH TRUE permite evaluar varias condiciones de arriba hacia abajo.
447
+ SWITCH (
448
+ TRUE (),
449
+ // Sin formato, no inventamos uno: devolvemos BLANK.
450
+ ISBLANK ( __MetricFormat ), BLANK (),
451
+ // Si es monetaria y falta simbolo, usamos $ como fallback didactico.
452
+ __Monetary = TRUE () && ISBLANK ( __CurrencySymbol ), "$ " & __MetricFormat,
453
+ // Si es monetaria y hay simbolo, lo ponemos delante del formato.
454
+ __Monetary = TRUE (), __CurrencySymbol & " " & __MetricFormat,
455
+ // Si no es monetaria, devolvemos el formato original.
456
+ __MetricFormat
457
+ )
458
+ lineageTag: fa141865-229b-4309-9618-aadd1a4e038f
459
+
460
+ /// Devuelve TRUE si alguna columna de la tabla Calendario está en el eje del visual (Fecha / Año / Trimestre / Mes / Año mes / Semana). Las medidas router (Actual, Previo) usan esto para decidir si respetar el eje del visual o aplicar el rango completo del período.
461
+ function EjeCalendarioEnContexto =
462
+ () =>
463
+ // Esta funcion responde una pregunta simple: el visual tiene una columna de Calendario en el eje?
464
+ // Si devuelve TRUE, las medidas deben respetar cada punto del eje temporal.
465
+ // Si devuelve FALSE, las medidas pueden calcular el total del rango seleccionado.
466
+ ISINSCOPE ( 'Calendario'[Fecha] )
467
+ // ISINSCOPE detecta si esta columna participa en el nivel visible del visual.
468
+ || ISINSCOPE ( 'Calendario'[Año] )
469
+ // Cada OR agrega otra granularidad temporal posible.
470
+ || ISINSCOPE ( 'Calendario'[Trimestre] )
471
+ || ISINSCOPE ( 'Calendario'[Mes] )
472
+ || ISINSCOPE ( 'Calendario'[Año mes] )
473
+ || ISINSCOPE ( 'Calendario'[Semana] )
474
+ lineageTag: 6f9014bc-cbde-419a-a944-6770c550d6e1
475
+
476
+ /// Formatea una etiqueta textual con la misma metadata centralizada que el formato numérico de la métrica activa. Usa Aux Métrica como fuente principal de selección y Métricas como fallback.
477
+ function FormatoValorEtiqueta =
478
+ ( metricValue : NUMERIC ) =>
479
+ // Esta funcion recibe un numero y lo convierte en texto para etiquetas de visuals.
480
+ VAR __Value =
481
+ // Guardamos el numero recibido para usarlo con un nombre mas claro.
482
+ metricValue
483
+ VAR __MetricName =
484
+ // Buscamos primero la metrica activa en Aux Metrica y luego en Metricas.
485
+ COALESCE (
486
+ SELECTEDVALUE ( '_GC Métrica'[Métrica] ),
487
+ SELECTEDVALUE ( 'Métricas'[Métrica] ),
488
+ // Si no hay seleccion, usamos Ventas como fallback del template.
489
+ "Ventas"
490
+ )
491
+ VAR __FormatString =
492
+ // Pedimos a otra UDF el formato correcto para esa metrica.
493
+ FormatoMetricaPorNombre ( __MetricName )
494
+ RETURN
495
+ // Si el valor esta vacio mostramos guion; si no, FORMAT lo convierte a texto.
496
+ IF ( ISBLANK ( __Value ), "-", FORMAT ( __Value, __FormatString ) )
497
+ lineageTag: 958d9e74-4b91-432d-b3b5-a1d5b0bf7792
498
+
499
+ /// Devuelve el formato semántico seguro de una métrica según la metadata de Métricas: tipo, decimales y moneda seleccionada. No aplica escalas ni sufijos para evitar doble abreviación en cards, ejes y matrices; conserva fallback para helpers heredados fuera del catálogo seleccionable.
500
+ function FormatoMetricaPorNombre =
501
+ ( pMetrica : STRING ) =>
502
+ // Esta funcion arma un formato numerico leyendo la metadata de una metrica por nombre.
503
+ VAR __TipoFormatoCatalogo =
504
+ // LOOKUPVALUE busca el tipo de formato de la metrica, por ejemplo Moneda o Porcentaje.
505
+ LOOKUPVALUE ( 'Métricas'[Tipo de formato], 'Métricas'[Métrica], pMetrica )
506
+ VAR __TipoFormatoHelper =
507
+ // Algunas medidas auxiliares siguen fuera del catalogo seleccionable de 56 metricas.
508
+ SWITCH (
509
+ pMetrica,
510
+ "Costo de ventas", "Moneda",
511
+ "Ventas nuevos clientes", "Moneda",
512
+ "Ventas nuevos clientes %", "Porcentaje"
513
+ )
514
+ VAR __TipoFormato =
515
+ COALESCE ( __TipoFormatoCatalogo, __TipoFormatoHelper )
516
+ VAR __FormatoFallback =
517
+ // Si el tipo no alcanza, usamos el formato textual guardado como respaldo.
518
+ LOOKUPVALUE ( 'Métricas'[Formato], 'Métricas'[Métrica], pMetrica )
519
+ VAR __MonetariaCatalogo =
520
+ LOOKUPVALUE ( 'Métricas'[Monetaria], 'Métricas'[Métrica], pMetrica )
521
+ VAR __MonetariaHelper =
522
+ pMetrica IN { "Costo de ventas", "Ventas nuevos clientes" }
523
+ VAR __Monetaria =
524
+ // COALESCE convierte un valor vacio en FALSE para evitar dudas en comparaciones.
525
+ COALESCE ( __MonetariaCatalogo, __MonetariaHelper, FALSE () )
526
+ VAR __Decimales =
527
+ // Leemos cuantos decimales debe mostrar la metrica; si falta, usamos 0.
528
+ COALESCE ( LOOKUPVALUE ( 'Métricas'[Decimales], 'Métricas'[Métrica], pMetrica ), 0 )
529
+ VAR __Symbol =
530
+ // Leemos el simbolo de moneda elegido por el usuario.
531
+ SELECTEDVALUE ( Monedas[Símbolo] )
532
+ VAR __CurrencyPrefix =
533
+ // Construimos el prefijo monetario solo cuando la metrica es monetaria.
534
+ SWITCH (
535
+ TRUE (),
536
+ __Monetaria <> TRUE (), "",
537
+ ISBLANK ( __Symbol ), "$ ",
538
+ __Symbol & " "
539
+ )
540
+ VAR __DecimalPattern =
541
+ // REPT repite ceros para armar la parte decimal del formato.
542
+ IF ( __Decimales > 0, "." & REPT ( "0", __Decimales ), "" )
543
+ VAR __NumberFormat =
544
+ // #,0 muestra miles y al menos un digito entero.
545
+ "#,0" & __DecimalPattern
546
+ VAR __PercentFormat =
547
+ // El formato de porcentaje usa 0 como entero base y agrega el signo %.
548
+ "0" & __DecimalPattern & "%"
549
+ VAR __MetricFormat =
550
+ // Elegimos el patron final segun el tipo de formato de la metrica.
551
+ SWITCH (
552
+ TRUE (),
553
+ __TipoFormato = "Porcentaje", __PercentFormat,
554
+ __TipoFormato IN { "Moneda", "Número" }, __NumberFormat,
555
+ __FormatoFallback
556
+ )
557
+ RETURN
558
+ // Si no hay formato devolvemos BLANK; si hay, agregamos prefijo de moneda cuando corresponde.
559
+ IF ( ISBLANK ( __MetricFormat ), BLANK (), __CurrencyPrefix & __MetricFormat )
560
+ lineageTag: 9679fb4f-8575-49a9-ab3e-f867818d2e93
561
+
562
+ /// Formatea etiquetas textuales compactas usando metadata de Métricas. No se usa como format string de medidas numéricas.
563
+ function FormatoValorCompacto =
564
+ ( metricValue : NUMERIC ) =>
565
+ // Esta funcion convierte un numero en una etiqueta compacta, por ejemplo $ 2 mill.
566
+ VAR __Value =
567
+ // Guardamos el numero recibido para reutilizarlo de forma clara.
568
+ metricValue
569
+ VAR __MetricName =
570
+ // Detectamos cual es la metrica activa; si no hay seleccion, usamos Ventas.
571
+ COALESCE (
572
+ SELECTEDVALUE ( '_GC Métrica'[Métrica] ),
573
+ SELECTEDVALUE ( 'Métricas'[Métrica] ),
574
+ "Ventas"
575
+ )
576
+ VAR __TipoFormato =
577
+ // Leemos si la metrica se comporta como moneda, numero o porcentaje.
578
+ LOOKUPVALUE ( 'Métricas'[Tipo de formato], 'Métricas'[Métrica], __MetricName )
579
+ VAR __Monetaria =
580
+ // Leemos si necesita simbolo de moneda; si falta metadata, asumimos que no.
581
+ COALESCE ( LOOKUPVALUE ( 'Métricas'[Monetaria], 'Métricas'[Métrica], __MetricName ), FALSE () )
582
+ VAR __DecimalesGlobal =
583
+ // Decimales generales de la metrica.
584
+ COALESCE ( LOOKUPVALUE ( 'Métricas'[Decimales], 'Métricas'[Métrica], __MetricName ), 0 )
585
+ VAR __DecimalesEtiqueta =
586
+ // Decimales especificos para etiquetas; si faltan, usamos los generales.
587
+ COALESCE ( LOOKUPVALUE ( 'Métricas'[Decimales etiqueta], 'Métricas'[Métrica], __MetricName ), __DecimalesGlobal )
588
+ VAR __EscalaEtiqueta =
589
+ // Escala decide si dividimos por miles, millones o dejamos el numero igual.
590
+ COALESCE ( LOOKUPVALUE ( 'Métricas'[Escala etiqueta], 'Métricas'[Métrica], __MetricName ), "Ninguna" )
591
+ VAR __SufijoEtiqueta =
592
+ // Sufijo visible, por ejemplo mill. o k.
593
+ COALESCE ( LOOKUPVALUE ( 'Métricas'[Sufijo etiqueta], 'Métricas'[Métrica], __MetricName ), "" )
594
+ VAR __Symbol =
595
+ // Simbolo de moneda elegido por el usuario.
596
+ SELECTEDVALUE ( Monedas[Símbolo] )
597
+ VAR __CurrencyPrefix =
598
+ // Si la metrica es monetaria agregamos simbolo; si no, no agregamos nada.
599
+ SWITCH (
600
+ TRUE (),
601
+ __Monetaria <> TRUE (), "",
602
+ ISBLANK ( __Symbol ), "$ ",
603
+ __Symbol & " "
604
+ )
605
+ VAR __Divisor =
606
+ // El divisor transforma el numero real en una version compacta.
607
+ SWITCH (
608
+ __EscalaEtiqueta,
609
+ "Millones", 1000000,
610
+ "Miles", 1000,
611
+ 1
612
+ )
613
+ VAR __ScaledValue =
614
+ // DIVIDE evita errores si algun divisor inesperado fuera cero.
615
+ DIVIDE ( __Value, __Divisor )
616
+ VAR __DecimalPattern =
617
+ // Armamos la cantidad de decimales que vera el usuario en la etiqueta.
618
+ IF ( __DecimalesEtiqueta > 0, "." & REPT ( "0", __DecimalesEtiqueta ), "" )
619
+ VAR __NumberFormat =
620
+ // Formato base para numeros compactos.
621
+ "#,0" & __DecimalPattern
622
+ VAR __PercentFormat =
623
+ // Formato especial para porcentajes, que no se escalan por miles o millones.
624
+ "0" & __DecimalPattern & "%"
625
+ VAR __Suffix =
626
+ // Si hay sufijo, agregamos un espacio antes para que el texto quede legible.
627
+ IF ( __SufijoEtiqueta = "", "", " " & __SufijoEtiqueta )
628
+ RETURN
629
+ // SWITCH TRUE elige que texto final devolver segun el caso.
630
+ SWITCH (
631
+ TRUE (),
632
+ ISBLANK ( __Value ), "-",
633
+ __TipoFormato = "Porcentaje", FORMAT ( __Value, __PercentFormat ),
634
+ __CurrencyPrefix & FORMAT ( __ScaledValue, __NumberFormat ) & __Suffix
635
+ )
636
+ lineageTag: d0dfaf8a-90ab-4896-8bbe-d1a1393454c6
637
+