@luquimbo/bi-superpowers 5.0.0 → 5.0.2

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 (196) hide show
  1. package/.claude-plugin/marketplace.json +5 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.claude-plugin/skill-manifest.json +23 -7
  4. package/.plugin/plugin.json +1 -1
  5. package/AGENTS.md +124 -26
  6. package/CHANGELOG.md +494 -16
  7. package/README.md +33 -117
  8. package/bin/cli.js +1 -1
  9. package/bin/commands/diff.js +2 -2
  10. package/bin/commands/install.js +58 -45
  11. package/bin/commands/lint.js +2 -2
  12. package/bin/commands/validate-projects.js +1 -1
  13. package/bin/lib/generators/claude-plugin.js +14 -5
  14. package/bin/lib/generators/shared.js +9 -5
  15. package/bin/lib/mcp-config.js +22 -2
  16. package/bin/lib/skills.js +8 -8
  17. package/bin/mcp/powerbi-modeling-launcher.js +8 -4
  18. package/bin/postinstall.js +14 -12
  19. package/bin/utils/mcp-detect.js +11 -11
  20. package/commands/bi-connect.md +34 -17
  21. package/commands/bi-dax.md +385 -0
  22. package/commands/bi-kickoff.md +75 -44
  23. package/commands/bi-modeling.md +395 -0
  24. package/commands/bi-performance.md +455 -0
  25. package/commands/bi-start.md +30 -18
  26. package/desktop-extension/manifest.json +2 -2
  27. package/package.json +6 -3
  28. package/skills/bi-connect/SKILL.md +34 -17
  29. package/skills/bi-connect/scripts/update-check.js +1 -1
  30. package/skills/bi-dax/SKILL.md +387 -0
  31. package/skills/{bi-report → bi-dax}/scripts/update-check.js +1 -1
  32. package/skills/bi-kickoff/SKILL.md +75 -44
  33. package/skills/bi-kickoff/scripts/update-check.js +1 -1
  34. package/skills/bi-modeling/SKILL.md +397 -0
  35. package/skills/bi-modeling/scripts/update-check.js +403 -0
  36. package/skills/bi-performance/SKILL.md +457 -0
  37. package/skills/bi-performance/scripts/install-tabular-editor.ps1 +90 -0
  38. package/skills/bi-performance/scripts/run-bpa.ps1 +161 -0
  39. package/skills/bi-performance/scripts/update-check.js +403 -0
  40. package/skills/bi-start/SKILL.md +31 -19
  41. package/skills/bi-start/scripts/update-check.js +1 -1
  42. package/src/content/base.md +13 -8
  43. package/src/content/routing.md +1 -5
  44. package/src/content/skills/bi-connect.md +32 -15
  45. package/src/content/skills/bi-dax.md +358 -0
  46. package/src/content/skills/bi-kickoff.md +73 -42
  47. package/src/content/skills/bi-modeling.md +368 -0
  48. package/src/content/skills/bi-performance/SKILL.md +428 -0
  49. package/src/content/skills/bi-performance/scripts/install-tabular-editor.ps1 +90 -0
  50. package/src/content/skills/bi-performance/scripts/run-bpa.ps1 +161 -0
  51. package/src/content/skills/bi-start.md +30 -18
  52. package/templates/sales/AGENTS.md +33 -0
  53. package/templates/sales/sales-template.Report/.platform +11 -0
  54. package/templates/sales/sales-template.Report/StaticResources/RegisteredResources/BISuperpowers.json +3888 -0
  55. package/templates/sales/sales-template.Report/StaticResources/SharedResources/BaseThemes/Fluent2-CY26SU03.json +4104 -0
  56. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/page.json +123 -0
  57. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/10420560e5b8c5235857/visual.json +16 -0
  58. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/2181c54a94f0c67abb2d/visual.json +283 -0
  59. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/24eba6a7af0b59974ef5/visual.json +703 -0
  60. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/26db24c91e5b615a5c29/mobile.json +11 -0
  61. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/26db24c91e5b615a5c29/visual.json +528 -0
  62. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/2ec652d0956901dd2afd/mobile.json +11 -0
  63. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/2ec652d0956901dd2afd/visual.json +324 -0
  64. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/45dda4e0b159becf2dcd/mobile.json +11 -0
  65. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/45dda4e0b159becf2dcd/visual.json +359 -0
  66. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/4ca8800cf1539ad423f2/visual.json +468 -0
  67. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/4f5704218eb88f7cdff6/mobile.json +29 -0
  68. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/4f5704218eb88f7cdff6/visual.json +241 -0
  69. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/54d3fdbedbbb863a9d7a/visual.json +575 -0
  70. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/68043403e96ca8ed23e8/visual.json +575 -0
  71. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/80b54a678ef36a250994/visual.json +351 -0
  72. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/814f624b6056dc4c8de5/mobile.json +11 -0
  73. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/814f624b6056dc4c8de5/visual.json +421 -0
  74. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/85e1cc13559f4e107ede/visual.json +681 -0
  75. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/8686961b837e855963fe/mobile.json +11 -0
  76. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/8686961b837e855963fe/visual.json +720 -0
  77. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/8d302c5b7e87e8cb57bb/visual.json +590 -0
  78. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/a02c5b30f2e757637d78/mobile.json +11 -0
  79. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/a02c5b30f2e757637d78/visual.json +102 -0
  80. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/a405d29e7744c770d445/visual.json +575 -0
  81. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/b0dc2036d3cf2baafb35/mobile.json +11 -0
  82. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/b0dc2036d3cf2baafb35/visual.json +333 -0
  83. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/cdd696baaf3b80b326f8/mobile.json +11 -0
  84. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/cdd696baaf3b80b326f8/visual.json +468 -0
  85. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/ff77ca1bafff5bfe5044/mobile.json +11 -0
  86. package/templates/sales/sales-template.Report/definition/pages/017e2c84c7dc89f26e57/visuals/ff77ca1bafff5bfe5044/visual.json +523 -0
  87. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/page.json +130 -0
  88. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/0352fd80d074693a65db/visual.json +681 -0
  89. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/1c5a14bf493697344b68/visual.json +351 -0
  90. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/mobile.json +11 -0
  91. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/3486cf7624c5b109b4e5/visual.json +333 -0
  92. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/mobile.json +11 -0
  93. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/4d8b989008edc0db28d1/visual.json +102 -0
  94. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/mobile.json +11 -0
  95. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/5f4d76bbc870118e9840/visual.json +468 -0
  96. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/mobile.json +11 -0
  97. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/73629e1abebb7a444b59/visual.json +359 -0
  98. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/749cb1388c7e0a88161c/visual.json +685 -0
  99. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/85090dcdf75ac2487d1e/visual.json +283 -0
  100. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/92cf92e3da10493adb78/visual.json +468 -0
  101. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a30bd0950630ed94e8a3/visual.json +590 -0
  102. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/mobile.json +11 -0
  103. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a56e91d9400a835e4814/visual.json +528 -0
  104. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a90aaa3e3117494f18f8/mobile.json +11 -0
  105. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/a90aaa3e3117494f18f8/visual.json +523 -0
  106. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/mobile.json +11 -0
  107. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/aded24cd205c0b528642/visual.json +720 -0
  108. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/mobile.json +37 -0
  109. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/af34b26f14a8a724c9a9/visual.json +1230 -0
  110. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/b06ef80aa78cabcef8a6/mobile.json +11 -0
  111. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/b06ef80aa78cabcef8a6/visual.json +324 -0
  112. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/d97979633a91e041107e/mobile.json +11 -0
  113. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/d97979633a91e041107e/visual.json +421 -0
  114. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/mobile.json +29 -0
  115. package/templates/sales/sales-template.Report/definition/pages/6a4808bb8bb9166f49ff/visuals/fa81f184e2cb0e8b087c/visual.json +241 -0
  116. package/templates/sales/sales-template.Report/definition/pages/pages.json +8 -0
  117. package/templates/sales/sales-template.Report/definition/report.json +89 -0
  118. package/templates/sales/sales-template.Report/definition/version.json +4 -0
  119. package/templates/sales/sales-template.Report/definition.pbir +9 -0
  120. package/templates/sales/sales-template.SemanticModel/.pbi/editorSettings.json +8 -0
  121. package/templates/sales/sales-template.SemanticModel/.platform +11 -0
  122. package/templates/sales/sales-template.SemanticModel/DAXQueries/.pbi/daxQueries.json +9 -0
  123. package/templates/sales/sales-template.SemanticModel/DAXQueries/Calendar445MonthNr.dax +0 -0
  124. package/templates/sales/sales-template.SemanticModel/DAXQueries/Consulta 1.dax +6 -0
  125. package/templates/sales/sales-template.SemanticModel/DAXQueries/Consulta 2.dax +32 -0
  126. package/templates/sales/sales-template.SemanticModel/definition/cultures/es-AR.tmdl +7324 -0
  127. package/templates/sales/sales-template.SemanticModel/definition/database.tmdl +3 -0
  128. package/templates/sales/sales-template.SemanticModel/definition/expressions.tmdl +233 -0
  129. package/templates/sales/sales-template.SemanticModel/definition/functions.tmdl +247 -0
  130. package/templates/sales/sales-template.SemanticModel/definition/model.tmdl +46 -0
  131. package/templates/sales/sales-template.SemanticModel/definition/relationships.tmdl +16 -0
  132. package/templates/sales/sales-template.SemanticModel/definition/tables/Aux Comparaciones.tmdl +194 -0
  133. package/templates/sales/sales-template.SemanticModel/definition/tables/Aux Dimensiones ventas.tmdl +71 -0
  134. package/templates/sales/sales-template.SemanticModel/definition/tables/Aux Ejes temporales.tmdl +67 -0
  135. package/templates/sales/sales-template.SemanticModel/definition/tables/Aux Per/303/255odos.tmdl" +318 -0
  136. package/templates/sales/sales-template.SemanticModel/definition/tables/Aux Vista de calendario.tmdl +36 -0
  137. package/templates/sales/sales-template.SemanticModel/definition/tables/Aux Vista del valor.tmdl +87 -0
  138. package/templates/sales/sales-template.SemanticModel/definition/tables/Aux Vista temporal.tmdl +62 -0
  139. package/templates/sales/sales-template.SemanticModel/definition/tables/Calendario.tmdl +198 -0
  140. package/templates/sales/sales-template.SemanticModel/definition/tables/Canales.tmdl +59 -0
  141. package/templates/sales/sales-template.SemanticModel/definition/tables/Clientes.tmdl +120 -0
  142. package/templates/sales/sales-template.SemanticModel/definition/tables/Modelo Configuraci/303/263n.tmdl" +48 -0
  143. package/templates/sales/sales-template.SemanticModel/definition/tables/Monedas.tmdl +43 -0
  144. package/templates/sales/sales-template.SemanticModel/definition/tables/M/303/251tricas.tmdl +553 -0
  145. package/templates/sales/sales-template.SemanticModel/definition/tables/Productos.tmdl +73 -0
  146. package/templates/sales/sales-template.SemanticModel/definition/tables/Tipo de cambio.tmdl +66 -0
  147. package/templates/sales/sales-template.SemanticModel/definition/tables/Ventas.tmdl +133 -0
  148. package/templates/sales/sales-template.SemanticModel/definition.pbism +5 -0
  149. package/templates/sales/sales-template.SemanticModel/diagramLayout.json +239 -0
  150. package/templates/sales/sales-template.pbip +14 -0
  151. package/theme/BISuperpowers.json +3888 -0
  152. package/commands/bi-report.md +0 -403
  153. package/skills/bi-report/SKILL.md +0 -405
  154. package/skills/bi-report/references/cli-commands.md +0 -184
  155. package/skills/bi-report/references/cli-setup.md +0 -101
  156. package/skills/bi-report/references/close-write-open-pattern.md +0 -80
  157. package/skills/bi-report/references/layouts/finance.md +0 -65
  158. package/skills/bi-report/references/layouts/generic.md +0 -46
  159. package/skills/bi-report/references/layouts/hr.md +0 -48
  160. package/skills/bi-report/references/layouts/marketing.md +0 -45
  161. package/skills/bi-report/references/layouts/operations.md +0 -44
  162. package/skills/bi-report/references/layouts/sales.md +0 -50
  163. package/skills/bi-report/references/native-visuals.md +0 -341
  164. package/skills/bi-report/references/pbi-desktop-installation.md +0 -87
  165. package/skills/bi-report/references/pbir-preview-activation.md +0 -40
  166. package/skills/bi-report/references/slicer.md +0 -89
  167. package/skills/bi-report/references/textbox.md +0 -101
  168. package/skills/bi-report/references/themes/BISuperpowers.json +0 -915
  169. package/skills/bi-report/references/troubleshooting.md +0 -135
  170. package/skills/bi-report/references/visual-types.md +0 -78
  171. package/skills/bi-report/scripts/apply-theme.js +0 -243
  172. package/skills/bi-report/scripts/create-visual.js +0 -942
  173. package/skills/bi-report/scripts/ensure-pbi-cli.sh +0 -41
  174. package/skills/bi-report/scripts/validate-pbir.js +0 -351
  175. package/src/content/skills/bi-report/SKILL.md +0 -376
  176. package/src/content/skills/bi-report/references/cli-commands.md +0 -184
  177. package/src/content/skills/bi-report/references/cli-setup.md +0 -101
  178. package/src/content/skills/bi-report/references/close-write-open-pattern.md +0 -80
  179. package/src/content/skills/bi-report/references/layouts/finance.md +0 -65
  180. package/src/content/skills/bi-report/references/layouts/generic.md +0 -46
  181. package/src/content/skills/bi-report/references/layouts/hr.md +0 -48
  182. package/src/content/skills/bi-report/references/layouts/marketing.md +0 -45
  183. package/src/content/skills/bi-report/references/layouts/operations.md +0 -44
  184. package/src/content/skills/bi-report/references/layouts/sales.md +0 -50
  185. package/src/content/skills/bi-report/references/native-visuals.md +0 -341
  186. package/src/content/skills/bi-report/references/pbi-desktop-installation.md +0 -87
  187. package/src/content/skills/bi-report/references/pbir-preview-activation.md +0 -40
  188. package/src/content/skills/bi-report/references/slicer.md +0 -89
  189. package/src/content/skills/bi-report/references/textbox.md +0 -101
  190. package/src/content/skills/bi-report/references/themes/BISuperpowers.json +0 -915
  191. package/src/content/skills/bi-report/references/troubleshooting.md +0 -135
  192. package/src/content/skills/bi-report/references/visual-types.md +0 -78
  193. package/src/content/skills/bi-report/scripts/apply-theme.js +0 -243
  194. package/src/content/skills/bi-report/scripts/create-visual.js +0 -942
  195. package/src/content/skills/bi-report/scripts/ensure-pbi-cli.sh +0 -41
  196. package/src/content/skills/bi-report/scripts/validate-pbir.js +0 -351
@@ -0,0 +1,194 @@
1
+ /// Presets M desconectados de comparación entre período actual y período previo para el template.
2
+ table 'Aux Comparaciones'
3
+ lineageTag: cd2fa428-f539-4001-8ede-7053e6051eae
4
+
5
+ column 'Vista de calendario'
6
+ dataType: string
7
+ isHidden
8
+ isNullable: false
9
+ lineageTag: 29b8452a-bff7-46a1-ab1c-e7034fb7f43b
10
+ summarizeBy: none
11
+ sourceColumn: Tipo Calendario
12
+
13
+ changedProperty = IsHidden
14
+
15
+ column Orden
16
+ dataType: int64
17
+ isHidden
18
+ isNullable: false
19
+ lineageTag: aa208cd9-679a-4ad9-96cc-2f5bc10a8805
20
+ summarizeBy: none
21
+ sourceColumn: Sort
22
+
23
+ column 'Comparación EN'
24
+ dataType: string
25
+ isHidden
26
+ isNullable: false
27
+ lineageTag: 84920ff5-91f5-4a8e-97e7-78dbc573ca69
28
+ summarizeBy: none
29
+ sourceColumn: Current period (vs. previous period)
30
+ sortByColumn: Orden
31
+
32
+ changedProperty = IsHidden
33
+
34
+ column Comparación
35
+ dataType: string
36
+ isNullable: false
37
+ lineageTag: 6e026f38-c1fe-43fc-93b4-fe3bdd8621d5
38
+ summarizeBy: none
39
+ sourceColumn: Período actual (vs. período previo)
40
+ sortByColumn: Orden
41
+
42
+ column FechaCurrentStart
43
+ dataType: dateTime
44
+ isHidden
45
+ formatString: Long Date
46
+ lineageTag: e1e3bc25-b0e2-4883-af11-eee0d4b50fb0
47
+ summarizeBy: none
48
+ sourceColumn: FechaCurrentStart
49
+
50
+ annotation UnderlyingDateTimeDataType = Date
51
+
52
+ column FechaCurrentEnd
53
+ dataType: dateTime
54
+ isHidden
55
+ formatString: Long Date
56
+ lineageTag: 5815193e-41d6-4189-a051-6bd9af9abb67
57
+ summarizeBy: none
58
+ sourceColumn: FechaCurrentEnd
59
+
60
+ annotation UnderlyingDateTimeDataType = Date
61
+
62
+ column FechaPrevioStart
63
+ dataType: dateTime
64
+ isHidden
65
+ formatString: Long Date
66
+ lineageTag: 0d00d66d-826a-450c-a2cc-7343f0862558
67
+ summarizeBy: none
68
+ sourceColumn: FechaPrevioStart
69
+
70
+ annotation UnderlyingDateTimeDataType = Date
71
+
72
+ column FechaPrevioEnd
73
+ dataType: dateTime
74
+ isHidden
75
+ formatString: Long Date
76
+ lineageTag: 41fab097-df10-4ac3-921e-1d776773c0bf
77
+ summarizeBy: none
78
+ sourceColumn: FechaPrevioEnd
79
+
80
+ annotation UnderlyingDateTimeDataType = Date
81
+
82
+ partition 'Calendar Comparisons' = m
83
+ mode: import
84
+ queryGroup: Calendario
85
+ source =
86
+ let
87
+ // Toma los periodos ya calculados por Aux Periodos.
88
+ PeriodsRaw = Table.Buffer(#"Aux Períodos"),
89
+ // Toma el catalogo editable de comparaciones visibles.
90
+ ComparisonPresets = Table.Buffer(#"Calendar Comparison Presets"),
91
+ TypesRaw = Table.Buffer(#"Calendar Types"),
92
+ // Normaliza nombres por si llegan en ingles o español.
93
+ Periods =
94
+ if Table.HasColumns(PeriodsRaw, {"Calendar Type", "Sort", "StartDate", "EndDate"}) then
95
+ Table.RenameColumns(
96
+ Table.SelectColumns(PeriodsRaw, {"Calendar Type", "Sort", "StartDate", "EndDate"}),
97
+ {{"Calendar Type", "CalendarType"}}
98
+ )
99
+ else
100
+ Table.RenameColumns(
101
+ Table.SelectColumns(PeriodsRaw, {"Vista de calendario", "Orden", "FechaInicio", "FechaFin"}),
102
+ {{"Vista de calendario", "CalendarType"}, {"Orden", "Sort"}, {"FechaInicio", "StartDate"}, {"FechaFin", "EndDate"}}
103
+ ),
104
+ // Normaliza las vistas de calendario disponibles.
105
+ Types =
106
+ if Table.HasColumns(TypesRaw, {"Calendar Type"}) then
107
+ Table.RenameColumns(Table.SelectColumns(TypesRaw, {"Calendar Type"}), {{"Calendar Type", "CalendarType"}})
108
+ else
109
+ Table.RenameColumns(Table.SelectColumns(TypesRaw, {"Vista de calendario"}), {{"Vista de calendario", "CalendarType"}}),
110
+ // Define que periodo actual y previo usa cada comparacion.
111
+ Map = #table(
112
+ type table [Sort = Int64.Type, CurrentSort = Int64.Type, PreviousSort = Int64.Type],
113
+ {
114
+ {1, 1, 2},
115
+ {2, 2, 3},
116
+ {9, 14, 15},
117
+ {10, 14, 16},
118
+ {11, 14, 18},
119
+ {12, 16, 17},
120
+ {13, 16, 19},
121
+ {14, 20, 21},
122
+ {15, 20, 22},
123
+ {16, 20, 24},
124
+ {17, 22, 23},
125
+ {18, 22, 25},
126
+ {19, 26, 27},
127
+ {20, 26, 28},
128
+ {21, 26, 30},
129
+ {22, 28, 29},
130
+ {23, 28, 31},
131
+ {24, 32, 34},
132
+ {25, 32, 35},
133
+ {26, 32, 37},
134
+ {27, 35, 36},
135
+ {28, 35, 38},
136
+ {29, 39, 41},
137
+ {30, 39, 40},
138
+ {31, 39, 43},
139
+ {32, 40, 42},
140
+ {33, 43, 43}
141
+ }
142
+ ),
143
+ // Une el catalogo visible con el mapa tecnico de rangos.
144
+ PresetsWithMap = Table.ExpandTableColumn(
145
+ Table.NestedJoin(ComparisonPresets, {"Sort"}, Map, {"Sort"}, "Map", JoinKind.LeftOuter),
146
+ "Map",
147
+ {"CurrentSort", "PreviousSort"},
148
+ {"CurrentSort", "PreviousSort"}
149
+ ),
150
+ // Duplica el catalogo para cada tipo de calendario disponible.
151
+ WithPresets = Table.AddColumn(Types, "Preset", each PresetsWithMap),
152
+ Base = Table.ExpandTableColumn(
153
+ WithPresets,
154
+ "Preset",
155
+ {"Sort", "Current period (vs. previous period)", "Período actual (vs. período previo)", "CurrentSort", "PreviousSort"},
156
+ {"Sort", "Current period (vs. previous period)", "Período actual (vs. período previo)", "CurrentSort", "PreviousSort"}
157
+ ),
158
+ // Busca fechas del periodo actual por calendario y orden.
159
+ WithCurrent = Table.NestedJoin(Base, {"CalendarType", "CurrentSort"}, Periods, {"CalendarType", "Sort"}, "CurrentPeriod", JoinKind.LeftOuter),
160
+ ExpandedCurrent = Table.ExpandTableColumn(WithCurrent, "CurrentPeriod", {"StartDate", "EndDate"}, {"FechaCurrentStart", "FechaCurrentEnd"}),
161
+ // Busca fechas del periodo previo con la misma regla.
162
+ WithPrevious = Table.NestedJoin(ExpandedCurrent, {"CalendarType", "PreviousSort"}, Periods, {"CalendarType", "Sort"}, "PreviousPeriod", JoinKind.LeftOuter),
163
+ ExpandedPrevious = Table.ExpandTableColumn(WithPrevious, "PreviousPeriod", {"StartDate", "EndDate"}, {"FechaPrevioStart", "FechaPrevioEnd"}),
164
+ // Conserva solo las columnas que usa el modelo.
165
+ Selected = Table.SelectColumns(
166
+ ExpandedPrevious,
167
+ {"CalendarType", "Sort", "Current period (vs. previous period)", "Período actual (vs. período previo)", "FechaCurrentStart", "FechaCurrentEnd", "FechaPrevioStart", "FechaPrevioEnd"}
168
+ ),
169
+ Renamed = Table.RenameColumns(Selected, {{"CalendarType", "Tipo Calendario"}}),
170
+ Typed = Table.TransformColumnTypes(
171
+ Renamed,
172
+ {
173
+ {"FechaCurrentStart", type date},
174
+ {"FechaCurrentEnd", type date},
175
+ {"FechaPrevioStart", type date},
176
+ {"FechaPrevioEnd", type date},
177
+ {"Tipo Calendario", type text},
178
+ {"Current period (vs. previous period)", type text},
179
+ {"Período actual (vs. período previo)", type text},
180
+ {"Sort", Int64.Type}
181
+ }
182
+ ),
183
+ // Corrige textos heredados sin tocar el catalogo editable.
184
+ FixedSpanish = Table.TransformColumns(
185
+ Typed,
186
+ {{"Período actual (vs. período previo)", each if _ = null then null else Text.Replace(Text.Replace(Text.Replace(Text.Replace(_, "Este semana", "Esta semana"), "mismo semana", "misma semana"), "semana pasada completo", "semana pasada completa"), "Histórico (vs. Histórico)", "Histórico (vs. histórico)"), type text}}
187
+ )
188
+ in
189
+ FixedSpanish
190
+
191
+ annotation PBI_NavigationStepName = Navegación
192
+
193
+ annotation PBI_ResultType = Table
194
+
@@ -0,0 +1,71 @@
1
+ /// Field parameter desconectado para elegir dinamicamente la dimension de desglose de tablas y matrices de ventas. Incluye campos descriptivos de las dimensiones relacionadas activamente con Ventas.
2
+ table 'Aux Dimensiones ventas'
3
+ lineageTag: cb2cb013-6cc7-40c8-a7bb-bdf78350f693
4
+
5
+ /// Etiqueta visible del field parameter para elegir la dimensión que se coloca dinámicamente en una tabla o matriz de ventas.
6
+ column 'Dimensión ventas'
7
+ lineageTag: 9a7fa2ef-fc93-41ce-b798-e64c8e90af45
8
+ summarizeBy: none
9
+ isNameInferred
10
+ sourceColumn: [Dimensión ventas]
11
+ sortByColumn: Orden
12
+
13
+ relatedColumnDetails
14
+ groupByColumn: Campo
15
+
16
+ /// Referencia NAMEOF usada internamente por Power BI como field parameter.
17
+ column Campo
18
+ isHidden
19
+ lineageTag: d9e4ef85-b90b-4d12-bc45-a3173e4ab8da
20
+ summarizeBy: none
21
+ isNameInferred
22
+ sourceColumn: [Campo]
23
+ sortByColumn: Orden
24
+
25
+ extendedProperty ParameterMetadata =
26
+ {
27
+ "version": 3,
28
+ "kind": 2
29
+ }
30
+
31
+ /// Orden de presentación del field parameter de dimensiones de ventas.
32
+ column Orden
33
+ isHidden
34
+ formatString: 0
35
+ lineageTag: 33c10dbf-4c92-4a3c-aac9-7e97c7158f2c
36
+ summarizeBy: sum
37
+ isNameInferred
38
+ sourceColumn: [Orden]
39
+
40
+ annotation SummarizationSetBy = Automatic
41
+
42
+ /// Grupo lógico de la dimensión incluida en el field parameter.
43
+ column 'Grupo dimensión'
44
+ lineageTag: c94a5cca-390b-4342-9ed2-31596867f62d
45
+ summarizeBy: none
46
+ isNameInferred
47
+ sourceColumn: [Grupo dimensión]
48
+
49
+ partition 'Aux Dimensiones ventas' = calculated
50
+ mode: import
51
+ source =
52
+ VAR __Parameter =
53
+ {
54
+ ( "Cliente", NAMEOF ( 'Clientes'[Cliente] ), 0, "Clientes" ),
55
+ ( "País", NAMEOF ( 'Clientes'[País] ), 1, "Clientes" ),
56
+ ( "Segmento cliente", NAMEOF ( 'Clientes'[Segmento] ), 2, "Clientes" ),
57
+ ( "Canal", NAMEOF ( 'Canales'[Canal] ), 3, "Canales" ),
58
+ ( "Tipo de canal", NAMEOF ( 'Canales'[Tipo de canal] ), 4, "Canales" ),
59
+ ( "Producto", NAMEOF ( 'Productos'[Producto] ), 5, "Productos" ),
60
+ ( "Categoría", NAMEOF ( 'Productos'[Categoría] ), 6, "Productos" ),
61
+ ( "Subcategoría", NAMEOF ( 'Productos'[Subcategoría] ), 7, "Productos" )
62
+ }
63
+ RETURN
64
+ SELECTCOLUMNS (
65
+ __Parameter,
66
+ "Dimensión ventas", [Value1],
67
+ "Campo", [Value2],
68
+ "Orden", [Value3],
69
+ "Grupo dimensión", [Value4]
70
+ )
71
+
@@ -0,0 +1,67 @@
1
+ /// Catálogo desconectado de granularidades de fecha. Field Parameter (kind=2) que
2
+ /// permite drivear el eje X dinámico de los visuales: el usuario elige Años / Trimestres /
3
+ /// Meses / Semanas / Días desde un slicer y los charts re-binding al campo correspondiente
4
+ /// de la tabla 'Fecha'. Filtrado adicional por 'Vista de calendario' (Gregoriano vs 4-4-5).
5
+ table 'Aux Ejes temporales'
6
+ lineageTag: 672638f2-b24a-4aff-a181-71078e5a1844
7
+
8
+ column 'Eje temporal'
9
+ lineageTag: d481b304-b1ae-4f38-b718-eb257d1c7e4b
10
+ summarizeBy: none
11
+ sourceColumn: [Value1]
12
+ sortByColumn: Orden
13
+
14
+ relatedColumnDetails
15
+ groupByColumn: Campo
16
+
17
+ annotation SummarizationSetBy = Automatic
18
+
19
+ column Campo
20
+ isHidden
21
+ lineageTag: c3332de0-e899-42c0-a3c3-3eb93f1e61fa
22
+ summarizeBy: none
23
+ sourceColumn: [Value2]
24
+ sortByColumn: Orden
25
+
26
+ extendedProperty ParameterMetadata =
27
+ {
28
+ "version": 3,
29
+ "kind": 2
30
+ }
31
+
32
+ annotation SummarizationSetBy = Automatic
33
+
34
+ column Orden
35
+ isHidden
36
+ formatString: 0
37
+ lineageTag: a75bdf5c-b3b9-446d-ad96-90a2fdbaf920
38
+ summarizeBy: sum
39
+ sourceColumn: [Value3]
40
+
41
+ annotation SummarizationSetBy = Automatic
42
+
43
+ column 'Vista de calendario'
44
+ dataType: string
45
+ isHidden
46
+ lineageTag: f9a3a1cc-ec82-4601-baad-6b683c55f7db
47
+ summarizeBy: none
48
+ sourceColumn: [Value4]
49
+
50
+ partition 'Ejes temporales' = calculated
51
+ mode: import
52
+ source =
53
+ {
54
+ ("Días", NAMEOF('Calendario'[Fecha]), 4, "Gregoriano"),
55
+ ("Semanas", NAMEOF('Calendario'[Semana]), 3, "Gregoriano"),
56
+ ("Meses", NAMEOF('Calendario'[Mes]), 2, "Gregoriano"),
57
+ ("Trimestres", NAMEOF('Calendario'[Trimestre]), 1, "Gregoriano"),
58
+ ("Años", NAMEOF('Calendario'[Año]), 0, "Gregoriano"),
59
+ ("Días", NAMEOF('Calendario'[Fecha]), 4, "Semanal 4-4-5"),
60
+ ("Semanas", NAMEOF('Calendario'[Semana]), 3, "Semanal 4-4-5"),
61
+ ("Meses", NAMEOF('Calendario'[Mes]), 2, "Semanal 4-4-5"),
62
+ ("Trimestres", NAMEOF('Calendario'[Trimestre]), 1, "Semanal 4-4-5"),
63
+ ("Años", NAMEOF('Calendario'[Año]), 0, "Semanal 4-4-5")
64
+ }
65
+
66
+ annotation PBI_Id = a16ad557b06f49098dee654bafb8f1b6
67
+
@@ -0,0 +1,318 @@
1
+ /// Presets M desconectados de períodos actuales para filtros rápidos del template.
2
+ table 'Aux Períodos'
3
+ lineageTag: 32f583da-e5a9-4582-b64b-3aae04d2dfeb
4
+
5
+ column 'Vista de calendario'
6
+ dataType: string
7
+ isNullable: false
8
+ lineageTag: 8306ad09-d5c2-480c-aaaf-ff0d39333793
9
+ summarizeBy: none
10
+ sourceColumn: Calendar Type
11
+
12
+ column Período
13
+ dataType: string
14
+ isNullable: false
15
+ lineageTag: ab4db080-b0f2-4aa1-9877-015dd8028866
16
+ summarizeBy: none
17
+ sourceColumn: Período
18
+ sortByColumn: Orden
19
+
20
+ column 'Período EN'
21
+ dataType: string
22
+ isHidden
23
+ isNullable: false
24
+ lineageTag: b96250ac-3027-432c-bb35-3397694af2e9
25
+ summarizeBy: none
26
+ sourceColumn: Period
27
+ sortByColumn: Orden
28
+
29
+ changedProperty = IsHidden
30
+
31
+ column Orden
32
+ dataType: int64
33
+ isHidden
34
+ isNullable: false
35
+ lineageTag: 9f1d6bf5-fa32-4d3a-98e3-bc1ef11fe03f
36
+ summarizeBy: none
37
+ sourceColumn: Sort
38
+
39
+ column FechaInicio
40
+ dataType: dateTime
41
+ isHidden
42
+ formatString: Long Date
43
+ lineageTag: 31742ee9-1a8a-4365-b42c-ed6b4d79c44c
44
+ summarizeBy: none
45
+ sourceColumn: StartDate
46
+
47
+ annotation UnderlyingDateTimeDataType = Date
48
+
49
+ column FechaFin
50
+ dataType: dateTime
51
+ isHidden
52
+ formatString: Long Date
53
+ lineageTag: 9d4df114-f4a6-4bec-8e4d-62b69b4c2572
54
+ summarizeBy: none
55
+ sourceColumn: EndDate
56
+
57
+ annotation UnderlyingDateTimeDataType = Date
58
+
59
+ partition 'Calendar Periods' = m
60
+ mode: import
61
+ queryGroup: Calendario
62
+ source =
63
+ let
64
+ // Usa la tabla Calendario (rolling Today) como base de todos los rangos.
65
+ Calendar = Table.Buffer(Calendario),
66
+ // Catalogo editable: el usuario controla que periodos existen.
67
+ Presets = Table.Buffer(#"Calendar Period Presets"),
68
+ Types = Table.SelectColumns(#"Calendar Types", {"Calendar Type"}),
69
+ // Today sale del maximo de Calendario (rolling).
70
+ Today = List.Max(Calendar[Fecha]),
71
+ Yesterday = Date.AddDays(Today, -1),
72
+ BeforeYesterday = Date.AddDays(Today, -2),
73
+ HistoricalStart = #date(2013, 6, 1),
74
+ // Rangos semanales gregorianos basados en lunes.
75
+ WeekStart = Date.StartOfWeek(Today, Day.Monday),
76
+ WeekEnd = Date.AddDays(WeekStart, 6),
77
+ PrevWeekStart = Date.AddDays(WeekStart, -7),
78
+ PrevWeekEnd = Date.AddDays(WeekStart, -1),
79
+ // Devuelve la menor fecha no nula entre dos opciones.
80
+ MinDate = (a as nullable date, b as nullable date) as nullable date => if a = null then b else if b = null then a else if a <= b then a else b,
81
+ // Suma dias solo cuando la fecha existe.
82
+ AddDaysSafe = (d as nullable date, n as number) as nullable date => if d = null then null else Date.AddDays(d, n),
83
+ // Busca inicio y fin de un periodo usando una clave fiscal.
84
+ RangeByKey = (columnName as text, key as nullable number) as record =>
85
+ let
86
+ rows = if key = null then #table({}, {}) else Table.SelectRows(Calendar, each Record.Field(_, columnName) = key),
87
+ startDate = if Table.IsEmpty(rows) then null else List.Min(rows[Fecha]),
88
+ endDate = if Table.IsEmpty(rows) then null else List.Max(rows[Fecha])
89
+ in
90
+ [Start = startDate, End = endDate],
91
+ // Busca la clave inmediatamente anterior a la clave actual.
92
+ MaxKeyBefore = (columnName as text, key as number) as nullable number =>
93
+ let
94
+ values = List.Distinct(List.RemoveNulls(Table.Column(Calendar, columnName))),
95
+ prior = List.Select(values, each _ < key)
96
+ in
97
+ if List.IsEmpty(prior) then null else List.Max(prior),
98
+ // Fila fiscal de la fecha actual para leer año, mes y trimestre.
99
+ CurrentFiscalRow = Table.SelectRows(Calendar, each [Fecha] = Today){0},
100
+ CurFY = CurrentFiscalRow[Fiscal445Year],
101
+ CurFM = CurrentFiscalRow[Fiscal445MonthNr],
102
+ CurFQ = CurrentFiscalRow[Fiscal445QuarterNr],
103
+ CurFS = CurrentFiscalRow[Fiscal445SemesterNr],
104
+ FiscalMonthKey = CurrentFiscalRow[Fiscal445MonthKey],
105
+ FiscalQuarterKey = CurrentFiscalRow[Fiscal445QuarterKey],
106
+ FiscalSemesterKey = CurrentFiscalRow[Fiscal445SemesterKey],
107
+ // Rangos mensuales fiscales 4-4-5.
108
+ FiscalMonthRange = RangeByKey("Fiscal445MonthKey", FiscalMonthKey),
109
+ PrevFiscalMonthKey = MaxKeyBefore("Fiscal445MonthKey", FiscalMonthKey),
110
+ PrevFiscalMonthRange = RangeByKey("Fiscal445MonthKey", PrevFiscalMonthKey),
111
+ FiscalTwoMonthsAgoKey = if PrevFiscalMonthKey = null then null else MaxKeyBefore("Fiscal445MonthKey", PrevFiscalMonthKey),
112
+ FiscalTwoMonthsAgoRange = RangeByKey("Fiscal445MonthKey", FiscalTwoMonthsAgoKey),
113
+ FiscalSameMonthLYRange = RangeByKey("Fiscal445MonthKey", (CurFY - 1) * 100 + CurFM),
114
+ FiscalPrevMonthLYRange = RangeByKey("Fiscal445MonthKey", if PrevFiscalMonthKey = null then null else (CurFY - 1) * 100 + Number.Mod(PrevFiscalMonthKey, 100)),
115
+ FiscalMonthOffset = Duration.Days(Today - FiscalMonthRange[Start]),
116
+ // Rangos trimestrales fiscales 4-4-5.
117
+ FiscalQuarterRange = RangeByKey("Fiscal445QuarterKey", FiscalQuarterKey),
118
+ PrevFiscalQuarterKey = MaxKeyBefore("Fiscal445QuarterKey", FiscalQuarterKey),
119
+ PrevFiscalQuarterRange = RangeByKey("Fiscal445QuarterKey", PrevFiscalQuarterKey),
120
+ FiscalTwoQuartersAgoKey = if PrevFiscalQuarterKey = null then null else MaxKeyBefore("Fiscal445QuarterKey", PrevFiscalQuarterKey),
121
+ FiscalTwoQuartersAgoRange = RangeByKey("Fiscal445QuarterKey", FiscalTwoQuartersAgoKey),
122
+ FiscalSameQuarterLYRange = RangeByKey("Fiscal445QuarterKey", (CurFY - 1) * 10 + CurFQ),
123
+ FiscalPrevQuarterLYRange = RangeByKey("Fiscal445QuarterKey", if PrevFiscalQuarterKey = null then null else (CurFY - 1) * 10 + Number.Mod(PrevFiscalQuarterKey, 10)),
124
+ FiscalQuarterOffset = Duration.Days(Today - FiscalQuarterRange[Start]),
125
+ // Rangos semestrales fiscales 4-4-5.
126
+ FiscalSemesterRange = RangeByKey("Fiscal445SemesterKey", FiscalSemesterKey),
127
+ PrevFiscalSemesterKey = MaxKeyBefore("Fiscal445SemesterKey", FiscalSemesterKey),
128
+ PrevFiscalSemesterRange = RangeByKey("Fiscal445SemesterKey", PrevFiscalSemesterKey),
129
+ FiscalTwoSemestersAgoKey = if PrevFiscalSemesterKey = null then null else MaxKeyBefore("Fiscal445SemesterKey", PrevFiscalSemesterKey),
130
+ FiscalTwoSemestersAgoRange = RangeByKey("Fiscal445SemesterKey", FiscalTwoSemestersAgoKey),
131
+ FiscalSameSemesterLYRange = RangeByKey("Fiscal445SemesterKey", (CurFY - 1) * 10 + CurFS),
132
+ FiscalPrevSemesterLYRange = RangeByKey("Fiscal445SemesterKey", if PrevFiscalSemesterKey = null then null else (CurFY - 1) * 10 + Number.Mod(PrevFiscalSemesterKey, 10)),
133
+ FiscalSemesterOffset = Duration.Days(Today - FiscalSemesterRange[Start]),
134
+ // Rangos anuales fiscales 4-4-5.
135
+ FiscalYearRange = RangeByKey("Fiscal445Year", CurFY),
136
+ FiscalPrevYearRange = RangeByKey("Fiscal445Year", CurFY - 1),
137
+ FiscalTwoYearsAgoRange = RangeByKey("Fiscal445Year", CurFY - 2),
138
+ FiscalYearOffset = Duration.Days(Today - FiscalYearRange[Start]),
139
+ // Rangos mensuales gregorianos.
140
+ GMonthStart = Date.StartOfMonth(Today),
141
+ GPrevMonthStart = Date.StartOfMonth(Date.AddMonths(Today, -1)),
142
+ GPrevMonthEnd = Date.EndOfMonth(Date.AddMonths(Today, -1)),
143
+ GTwoMonthsAgoStart = Date.StartOfMonth(Date.AddMonths(Today, -2)),
144
+ GTwoMonthsAgoEnd = Date.EndOfMonth(Date.AddMonths(Today, -2)),
145
+ GSameMonthLYStart = Date.AddYears(GMonthStart, -1),
146
+ GSameMonthLYEnd = Date.EndOfMonth(Date.AddYears(GMonthStart, -1)),
147
+ GPrevMonthLYStart = Date.AddYears(GPrevMonthStart, -1),
148
+ GPrevMonthLYEnd = Date.EndOfMonth(Date.AddYears(GPrevMonthStart, -1)),
149
+ GMonthOffset = Duration.Days(Today - GMonthStart),
150
+ // Rangos trimestrales gregorianos.
151
+ GQuarterStartMonth = 3 * Number.IntegerDivide(Date.Month(Today) - 1, 3) + 1,
152
+ GQuarterStart = #date(Date.Year(Today), GQuarterStartMonth, 1),
153
+ GPrevQuarterStart = Date.AddMonths(GQuarterStart, -3),
154
+ GPrevQuarterEnd = Date.AddDays(GQuarterStart, -1),
155
+ GTwoQuartersAgoStart = Date.AddMonths(GQuarterStart, -6),
156
+ GTwoQuartersAgoEnd = Date.AddDays(GPrevQuarterStart, -1),
157
+ GSameQuarterLYStart = Date.AddYears(GQuarterStart, -1),
158
+ GSameQuarterLYEnd = Date.AddDays(Date.AddMonths(GQuarterStart, -9), -1),
159
+ GPrevQuarterLYStart = Date.AddYears(GPrevQuarterStart, -1),
160
+ GPrevQuarterLYEnd = Date.AddYears(GPrevQuarterEnd, -1),
161
+ GQuarterOffset = Duration.Days(Today - GQuarterStart),
162
+ // Rangos semestrales gregorianos.
163
+ GSemesterStart = #date(Date.Year(Today), if Date.Month(Today) <= 6 then 1 else 7, 1),
164
+ GPrevSemesterStart = Date.AddMonths(GSemesterStart, -6),
165
+ GPrevSemesterEnd = Date.AddDays(GSemesterStart, -1),
166
+ GTwoSemestersAgoStart = Date.AddMonths(GSemesterStart, -12),
167
+ GTwoSemestersAgoEnd = Date.AddDays(GPrevSemesterStart, -1),
168
+ GSameSemesterLYStart = Date.AddYears(GSemesterStart, -1),
169
+ GSameSemesterLYEnd = Date.AddDays(Date.AddMonths(GSemesterStart, -6), -1),
170
+ GPrevSemesterLYStart = Date.AddYears(GPrevSemesterStart, -1),
171
+ GPrevSemesterLYEnd = Date.AddYears(GPrevSemesterEnd, -1),
172
+ GSemesterOffset = Duration.Days(Today - GSemesterStart),
173
+ // Rangos anuales gregorianos.
174
+ GYearStart = #date(Date.Year(Today), 1, 1),
175
+ GPrevYearStart = #date(Date.Year(Today) - 1, 1, 1),
176
+ GPrevYearEnd = #date(Date.Year(Today) - 1, 12, 31),
177
+ GTwoYearsAgoStart = #date(Date.Year(Today) - 2, 1, 1),
178
+ GTwoYearsAgoEnd = #date(Date.Year(Today) - 2, 12, 31),
179
+ GYearOffset = Duration.Days(Today - GYearStart),
180
+ // Crea todas las combinaciones de tipo de calendario y periodo.
181
+ WithPresets = Table.AddColumn(Types, "Preset", each Presets),
182
+ Base = Table.ExpandTableColumn(WithPresets, "Preset", {"Período", "Period", "Sort"}),
183
+ // Calcula StartDate y EndDate segun el Sort elegido.
184
+ WithRange = Table.AddColumn(Base, "Range", each
185
+ let
186
+ sort = [Sort],
187
+ is445 = [Calendar Type] = "Semanal 4-4-5",
188
+ startDate =
189
+ if sort = 1 then Today
190
+ else if sort = 2 then Yesterday
191
+ else if sort = 3 then BeforeYesterday
192
+ else if sort = 4 then Date.AddDays(Yesterday, -6)
193
+ else if sort = 5 then Date.AddDays(Yesterday, -13)
194
+ else if sort = 6 then Date.AddDays(Yesterday, -29)
195
+ else if sort = 7 then Date.AddDays(Yesterday, -59)
196
+ else if sort = 8 then Date.AddDays(Yesterday, -89)
197
+ else if sort = 9 then Date.AddDays(Yesterday, -179)
198
+ else if sort = 10 then Date.AddDays(Yesterday, -179)
199
+ else if sort = 11 then Date.AddDays(Yesterday, -359)
200
+ else if sort = 12 then Date.AddDays(Yesterday, -364)
201
+ else if sort = 13 then Date.AddDays(Yesterday, -729)
202
+ else if sort = 14 then WeekStart
203
+ else if List.Contains({15, 16}, sort) then PrevWeekStart
204
+ else if sort = 17 then Date.AddDays(WeekStart, -14)
205
+ else if sort = 18 then Date.AddDays(WeekStart, -364)
206
+ else if sort = 19 then Date.AddDays(PrevWeekStart, -364)
207
+ else if is445 and sort = 20 then FiscalMonthRange[Start]
208
+ else if sort = 20 then GMonthStart
209
+ else if is445 and List.Contains({21, 22}, sort) then PrevFiscalMonthRange[Start]
210
+ else if List.Contains({21, 22}, sort) then GPrevMonthStart
211
+ else if is445 and sort = 23 then FiscalTwoMonthsAgoRange[Start]
212
+ else if sort = 23 then GTwoMonthsAgoStart
213
+ else if is445 and sort = 24 then FiscalSameMonthLYRange[Start]
214
+ else if sort = 24 then GSameMonthLYStart
215
+ else if is445 and sort = 25 then FiscalPrevMonthLYRange[Start]
216
+ else if sort = 25 then GPrevMonthLYStart
217
+ else if is445 and sort = 26 then FiscalQuarterRange[Start]
218
+ else if sort = 26 then GQuarterStart
219
+ else if is445 and List.Contains({27, 28}, sort) then PrevFiscalQuarterRange[Start]
220
+ else if List.Contains({27, 28}, sort) then GPrevQuarterStart
221
+ else if is445 and sort = 29 then FiscalTwoQuartersAgoRange[Start]
222
+ else if sort = 29 then GTwoQuartersAgoStart
223
+ else if is445 and sort = 30 then FiscalSameQuarterLYRange[Start]
224
+ else if sort = 30 then GSameQuarterLYStart
225
+ else if is445 and sort = 31 then FiscalPrevQuarterLYRange[Start]
226
+ else if sort = 31 then GPrevQuarterLYStart
227
+ else if is445 and sort = 32 then FiscalSemesterRange[Start]
228
+ else if sort = 32 then GSemesterStart
229
+ else if is445 and List.Contains({33, 34, 35}, sort) then PrevFiscalSemesterRange[Start]
230
+ else if List.Contains({33, 34, 35}, sort) then GPrevSemesterStart
231
+ else if is445 and sort = 36 then FiscalTwoSemestersAgoRange[Start]
232
+ else if sort = 36 then GTwoSemestersAgoStart
233
+ else if is445 and sort = 37 then FiscalSameSemesterLYRange[Start]
234
+ else if sort = 37 then GSameSemesterLYStart
235
+ else if is445 and sort = 38 then FiscalPrevSemesterLYRange[Start]
236
+ else if sort = 38 then GPrevSemesterLYStart
237
+ else if is445 and sort = 39 then FiscalYearRange[Start]
238
+ else if sort = 39 then GYearStart
239
+ else if is445 and List.Contains({40, 41}, sort) then FiscalPrevYearRange[Start]
240
+ else if List.Contains({40, 41}, sort) then GPrevYearStart
241
+ else if is445 and sort = 42 then FiscalTwoYearsAgoRange[Start]
242
+ else if sort = 42 then GTwoYearsAgoStart
243
+ else HistoricalStart,
244
+ endDate =
245
+ if sort = 1 then Today
246
+ else if sort = 2 then Yesterday
247
+ else if sort = 3 then BeforeYesterday
248
+ else if sort = 4 then Yesterday
249
+ else if sort = 5 then Date.AddDays(Yesterday, -7)
250
+ else if sort = 6 then Yesterday
251
+ else if sort = 7 then Date.AddDays(Yesterday, -30)
252
+ else if sort = 8 then Yesterday
253
+ else if sort = 9 then Date.AddDays(Yesterday, -90)
254
+ else if sort = 10 then Yesterday
255
+ else if sort = 11 then Date.AddDays(Yesterday, -180)
256
+ else if sort = 12 then Yesterday
257
+ else if sort = 13 then Date.AddDays(Yesterday, -365)
258
+ else if sort = 14 then Today
259
+ else if sort = 15 then Date.AddDays(Today, -7)
260
+ else if sort = 16 then PrevWeekEnd
261
+ else if sort = 17 then Date.AddDays(WeekEnd, -14)
262
+ else if sort = 18 then Date.AddDays(Today, -364)
263
+ else if sort = 19 then Date.AddDays(PrevWeekEnd, -364)
264
+ else if sort = 20 then Today
265
+ else if is445 and sort = 21 then AddDaysSafe(PrevFiscalMonthRange[Start], FiscalMonthOffset)
266
+ else if sort = 21 then MinDate(GPrevMonthEnd, Date.AddDays(GPrevMonthStart, GMonthOffset))
267
+ else if is445 and sort = 22 then PrevFiscalMonthRange[End]
268
+ else if sort = 22 then GPrevMonthEnd
269
+ else if is445 and sort = 23 then FiscalTwoMonthsAgoRange[End]
270
+ else if sort = 23 then GTwoMonthsAgoEnd
271
+ else if is445 and sort = 24 then AddDaysSafe(FiscalSameMonthLYRange[Start], FiscalMonthOffset)
272
+ else if sort = 24 then MinDate(GSameMonthLYEnd, Date.AddDays(GSameMonthLYStart, GMonthOffset))
273
+ else if is445 and sort = 25 then FiscalPrevMonthLYRange[End]
274
+ else if sort = 25 then GPrevMonthLYEnd
275
+ else if sort = 26 then Today
276
+ else if is445 and sort = 27 then AddDaysSafe(PrevFiscalQuarterRange[Start], FiscalQuarterOffset)
277
+ else if sort = 27 then MinDate(GPrevQuarterEnd, Date.AddDays(GPrevQuarterStart, GQuarterOffset))
278
+ else if is445 and sort = 28 then PrevFiscalQuarterRange[End]
279
+ else if sort = 28 then GPrevQuarterEnd
280
+ else if is445 and sort = 29 then FiscalTwoQuartersAgoRange[End]
281
+ else if sort = 29 then GTwoQuartersAgoEnd
282
+ else if is445 and sort = 30 then AddDaysSafe(FiscalSameQuarterLYRange[Start], FiscalQuarterOffset)
283
+ else if sort = 30 then MinDate(GSameQuarterLYEnd, Date.AddDays(GSameQuarterLYStart, GQuarterOffset))
284
+ else if is445 and sort = 31 then FiscalPrevQuarterLYRange[End]
285
+ else if sort = 31 then GPrevQuarterLYEnd
286
+ else if sort = 32 then Today
287
+ else if is445 and sort = 33 then PrevFiscalSemesterRange[End]
288
+ else if sort = 33 then GPrevSemesterEnd
289
+ else if is445 and sort = 34 then AddDaysSafe(PrevFiscalSemesterRange[Start], FiscalSemesterOffset)
290
+ else if sort = 34 then MinDate(GPrevSemesterEnd, Date.AddDays(GPrevSemesterStart, GSemesterOffset))
291
+ else if is445 and sort = 35 then PrevFiscalSemesterRange[End]
292
+ else if sort = 35 then GPrevSemesterEnd
293
+ else if is445 and sort = 36 then FiscalTwoSemestersAgoRange[End]
294
+ else if sort = 36 then GTwoSemestersAgoEnd
295
+ else if is445 and sort = 37 then AddDaysSafe(FiscalSameSemesterLYRange[Start], FiscalSemesterOffset)
296
+ else if sort = 37 then MinDate(GSameSemesterLYEnd, Date.AddDays(GSameSemesterLYStart, GSemesterOffset))
297
+ else if is445 and sort = 38 then FiscalPrevSemesterLYRange[End]
298
+ else if sort = 38 then GPrevSemesterLYEnd
299
+ else if sort = 39 then Today
300
+ else if is445 and sort = 40 then FiscalPrevYearRange[End]
301
+ else if sort = 40 then GPrevYearEnd
302
+ else if is445 and sort = 41 then AddDaysSafe(FiscalPrevYearRange[Start], FiscalYearOffset)
303
+ else if sort = 41 then MinDate(GPrevYearEnd, Date.AddDays(GPrevYearStart, GYearOffset))
304
+ else if is445 and sort = 42 then FiscalTwoYearsAgoRange[End]
305
+ else if sort = 42 then GTwoYearsAgoEnd
306
+ else Today
307
+ in
308
+ [StartDate = startDate, EndDate = endDate], type record),
309
+ Expanded = Table.ExpandRecordColumn(WithRange, "Range", {"StartDate", "EndDate"}, {"StartDate", "EndDate"}),
310
+ // Fija tipos para que DAX reciba fechas y textos correctos.
311
+ Typed = Table.TransformColumnTypes(Expanded,{{"StartDate", type date}, {"EndDate", type date}, {"Calendar Type", type text}, {"Período", type text}, {"Period", type text}, {"Sort", Int64.Type}})
312
+ in
313
+ Typed
314
+
315
+ annotation PBI_NavigationStepName = Navegación
316
+
317
+ annotation PBI_ResultType = Table
318
+