@luquimbo/bi-superpowers 3.1.1 → 3.2.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 (107) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.claude-plugin/skill-manifest.json +1 -1
  4. package/.plugin/plugin.json +1 -1
  5. package/bin/build-plugin.js +6 -6
  6. package/bin/cli.js +169 -310
  7. package/bin/commands/install.js +87 -70
  8. package/bin/lib/agents.js +19 -0
  9. package/bin/lib/mcp-config.js +23 -4
  10. package/desktop-extension/manifest.json +4 -11
  11. package/desktop-extension/server.js +34 -25
  12. package/package.json +3 -9
  13. package/skills/pbi-connect/SKILL.md +1 -1
  14. package/skills/project-kickoff/SKILL.md +1 -1
  15. package/bin/commands/add.js +0 -533
  16. package/bin/commands/add.test.js +0 -77
  17. package/bin/commands/changelog.js +0 -443
  18. package/bin/commands/pull.js +0 -287
  19. package/bin/commands/pull.test.js +0 -36
  20. package/bin/commands/push.js +0 -231
  21. package/bin/commands/push.test.js +0 -14
  22. package/bin/commands/search.js +0 -344
  23. package/bin/commands/search.test.js +0 -115
  24. package/bin/commands/setup.js +0 -545
  25. package/bin/commands/setup.test.js +0 -46
  26. package/bin/commands/sync-profile.js +0 -405
  27. package/bin/commands/sync-profile.test.js +0 -14
  28. package/bin/commands/sync-source.js +0 -418
  29. package/bin/commands/sync-source.test.js +0 -14
  30. package/bin/utils/errors.js +0 -159
  31. package/bin/utils/git.js +0 -298
  32. package/bin/utils/logger.js +0 -142
  33. package/bin/utils/pbix.js +0 -305
  34. package/bin/utils/pbix.test.js +0 -37
  35. package/bin/utils/profiles.js +0 -312
  36. package/bin/utils/projects.js +0 -169
  37. package/bin/utils/readline.js +0 -206
  38. package/bin/utils/readline.test.js +0 -47
  39. package/docs/openrouter-free-models.md +0 -92
  40. package/library/examples/README.md +0 -151
  41. package/library/examples/finance-reporting/README.md +0 -351
  42. package/library/examples/finance-reporting/data-model.md +0 -267
  43. package/library/examples/finance-reporting/measures.dax +0 -557
  44. package/library/examples/hr-analytics/README.md +0 -371
  45. package/library/examples/hr-analytics/data-model.md +0 -315
  46. package/library/examples/hr-analytics/measures.dax +0 -460
  47. package/library/examples/marketing-analytics/README.md +0 -37
  48. package/library/examples/marketing-analytics/data-model.md +0 -62
  49. package/library/examples/marketing-analytics/measures.dax +0 -110
  50. package/library/examples/retail-analytics/README.md +0 -439
  51. package/library/examples/retail-analytics/data-model.md +0 -288
  52. package/library/examples/retail-analytics/measures.dax +0 -481
  53. package/library/examples/supply-chain/README.md +0 -37
  54. package/library/examples/supply-chain/data-model.md +0 -69
  55. package/library/examples/supply-chain/measures.dax +0 -77
  56. package/library/examples/udf-library/README.md +0 -228
  57. package/library/examples/udf-library/functions.dax +0 -571
  58. package/library/snippets/dax/README.md +0 -292
  59. package/library/snippets/dax/business-domains.md +0 -576
  60. package/library/snippets/dax/calculate-patterns.md +0 -276
  61. package/library/snippets/dax/calculation-groups.md +0 -489
  62. package/library/snippets/dax/error-handling.md +0 -495
  63. package/library/snippets/dax/iterators-and-aggregations.md +0 -474
  64. package/library/snippets/dax/kpis-and-metrics.md +0 -293
  65. package/library/snippets/dax/rankings-and-topn.md +0 -235
  66. package/library/snippets/dax/security-patterns.md +0 -413
  67. package/library/snippets/dax/text-and-formatting.md +0 -316
  68. package/library/snippets/dax/time-intelligence.md +0 -196
  69. package/library/snippets/dax/user-defined-functions.md +0 -477
  70. package/library/snippets/dax/virtual-tables.md +0 -546
  71. package/library/snippets/excel-formulas/README.md +0 -84
  72. package/library/snippets/excel-formulas/aggregations.md +0 -330
  73. package/library/snippets/excel-formulas/dates-and-times.md +0 -361
  74. package/library/snippets/excel-formulas/dynamic-arrays.md +0 -314
  75. package/library/snippets/excel-formulas/lookups.md +0 -169
  76. package/library/snippets/excel-formulas/text-functions.md +0 -363
  77. package/library/snippets/governance/naming-conventions.md +0 -97
  78. package/library/snippets/governance/review-checklists.md +0 -107
  79. package/library/snippets/power-query/README.md +0 -389
  80. package/library/snippets/power-query/api-integration.md +0 -707
  81. package/library/snippets/power-query/connections.md +0 -434
  82. package/library/snippets/power-query/data-cleaning.md +0 -298
  83. package/library/snippets/power-query/error-handling.md +0 -526
  84. package/library/snippets/power-query/parameters.md +0 -350
  85. package/library/snippets/power-query/performance.md +0 -506
  86. package/library/snippets/power-query/transformations.md +0 -330
  87. package/library/snippets/report-design/accessibility.md +0 -78
  88. package/library/snippets/report-design/chart-selection.md +0 -54
  89. package/library/snippets/report-design/layout-patterns.md +0 -87
  90. package/library/templates/data-models/README.md +0 -93
  91. package/library/templates/data-models/finance-model.md +0 -627
  92. package/library/templates/data-models/retail-star-schema.md +0 -473
  93. package/library/templates/excel/README.md +0 -83
  94. package/library/templates/excel/budget-tracker.md +0 -432
  95. package/library/templates/excel/data-entry-form.md +0 -533
  96. package/library/templates/power-bi/README.md +0 -72
  97. package/library/templates/power-bi/finance-report.md +0 -449
  98. package/library/templates/power-bi/kpi-scorecard.md +0 -461
  99. package/library/templates/power-bi/sales-dashboard.md +0 -281
  100. package/library/themes/excel/README.md +0 -436
  101. package/library/themes/power-bi/README.md +0 -271
  102. package/library/themes/power-bi/accessible.json +0 -307
  103. package/library/themes/power-bi/bi-superpowers-default.json +0 -858
  104. package/library/themes/power-bi/corporate-blue.json +0 -291
  105. package/library/themes/power-bi/dark-mode.json +0 -291
  106. package/library/themes/power-bi/minimal.json +0 -292
  107. package/library/themes/power-bi/print-friendly.json +0 -309
@@ -1,481 +0,0 @@
1
- // ============================================================================
2
- // RETAIL ANALYTICS - DAX MEASURE LIBRARY
3
- // ============================================================================
4
- // Organized by category for easy navigation and maintenance
5
- // All measures follow BI Agent Superpowers naming conventions
6
- // ============================================================================
7
-
8
-
9
- // ----------------------------------------------------------------------------
10
- // BASE MEASURES
11
- // ----------------------------------------------------------------------------
12
-
13
- Revenue =
14
- SUM(FactSales[Amount])
15
-
16
- Cost =
17
- SUMX(
18
- FactSales,
19
- FactSales[Quantity] * RELATED(DimProduct[UnitCost])
20
- )
21
-
22
- Profit =
23
- [Revenue] - [Cost]
24
-
25
- Profit Margin % =
26
- DIVIDE([Profit], [Revenue])
27
-
28
- Quantity =
29
- SUM(FactSales[Quantity])
30
-
31
- Transactions =
32
- COUNTROWS(FactSales)
33
-
34
- Avg Order Value =
35
- DIVIDE([Revenue], [Transactions])
36
-
37
- Avg Unit Price =
38
- DIVIDE([Revenue], [Quantity])
39
-
40
-
41
- // ----------------------------------------------------------------------------
42
- // TIME INTELLIGENCE - YEAR-TO-DATE
43
- // ----------------------------------------------------------------------------
44
-
45
- Revenue YTD =
46
- TOTALYTD([Revenue], DimDate[Date])
47
-
48
- Profit YTD =
49
- TOTALYTD([Profit], DimDate[Date])
50
-
51
- Quantity YTD =
52
- TOTALYTD([Quantity], DimDate[Date])
53
-
54
-
55
- // ----------------------------------------------------------------------------
56
- // TIME INTELLIGENCE - PRIOR YEAR
57
- // ----------------------------------------------------------------------------
58
-
59
- Revenue PY =
60
- CALCULATE(
61
- [Revenue],
62
- SAMEPERIODLASTYEAR(DimDate[Date])
63
- )
64
-
65
- Profit PY =
66
- CALCULATE(
67
- [Profit],
68
- SAMEPERIODLASTYEAR(DimDate[Date])
69
- )
70
-
71
- Revenue YTD PY =
72
- CALCULATE(
73
- [Revenue YTD],
74
- SAMEPERIODLASTYEAR(DimDate[Date])
75
- )
76
-
77
-
78
- // ----------------------------------------------------------------------------
79
- // TIME INTELLIGENCE - GROWTH RATES
80
- // ----------------------------------------------------------------------------
81
-
82
- Revenue YoY % =
83
- VAR _Current = [Revenue]
84
- VAR _PY = [Revenue PY]
85
- RETURN
86
- DIVIDE(_Current - _PY, _PY)
87
-
88
- Revenue YoY Var =
89
- [Revenue] - [Revenue PY]
90
-
91
- Profit YoY % =
92
- VAR _Current = [Profit]
93
- VAR _PY = [Profit PY]
94
- RETURN
95
- DIVIDE(_Current - _PY, _PY)
96
-
97
- Revenue YTD YoY % =
98
- VAR _Current = [Revenue YTD]
99
- VAR _PY = [Revenue YTD PY]
100
- RETURN
101
- DIVIDE(_Current - _PY, _PY)
102
-
103
-
104
- // ----------------------------------------------------------------------------
105
- // TIME INTELLIGENCE - ROLLING PERIODS
106
- // ----------------------------------------------------------------------------
107
-
108
- Revenue R3M =
109
- CALCULATE(
110
- [Revenue],
111
- DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -3, MONTH)
112
- )
113
-
114
- Revenue R12M =
115
- CALCULATE(
116
- [Revenue],
117
- DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -12, MONTH)
118
- )
119
-
120
- Revenue R3M Avg =
121
- AVERAGEX(
122
- DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -3, MONTH),
123
- [Revenue]
124
- )
125
-
126
-
127
- // ----------------------------------------------------------------------------
128
- // TIME INTELLIGENCE - MONTH COMPARISONS
129
- // ----------------------------------------------------------------------------
130
-
131
- Revenue PM =
132
- CALCULATE(
133
- [Revenue],
134
- PREVIOUSMONTH(DimDate[Date])
135
- )
136
-
137
- Revenue MoM % =
138
- VAR _Current = [Revenue]
139
- VAR _PM = [Revenue PM]
140
- RETURN
141
- DIVIDE(_Current - _PM, _PM)
142
-
143
-
144
- // ----------------------------------------------------------------------------
145
- // RANKINGS
146
- // ----------------------------------------------------------------------------
147
-
148
- Product Rank =
149
- IF(
150
- HASONEVALUE(DimProduct[ProductName]),
151
- RANKX(
152
- ALL(DimProduct[ProductName]),
153
- [Revenue],
154
- ,
155
- DESC,
156
- DENSE
157
- )
158
- )
159
-
160
- Store Rank =
161
- IF(
162
- HASONEVALUE(DimStore[StoreName]),
163
- RANKX(
164
- ALL(DimStore[StoreName]),
165
- [Revenue],
166
- ,
167
- DESC,
168
- DENSE
169
- )
170
- )
171
-
172
- Customer Rank =
173
- IF(
174
- HASONEVALUE(DimCustomer[CustomerName]),
175
- RANKX(
176
- ALL(DimCustomer[CustomerName]),
177
- [Revenue],
178
- ,
179
- DESC,
180
- DENSE
181
- )
182
- )
183
-
184
- Category Rank =
185
- IF(
186
- HASONEVALUE(DimProduct[Category]),
187
- RANKX(
188
- ALL(DimProduct[Category]),
189
- [Revenue],
190
- ,
191
- DESC,
192
- DENSE
193
- )
194
- )
195
-
196
-
197
- // ----------------------------------------------------------------------------
198
- // TOP N CALCULATIONS
199
- // ----------------------------------------------------------------------------
200
-
201
- Revenue Top 10 Products =
202
- CALCULATE(
203
- [Revenue],
204
- TOPN(10, ALL(DimProduct[ProductName]), [Revenue], DESC)
205
- )
206
-
207
- Revenue Top 5 Customers =
208
- CALCULATE(
209
- [Revenue],
210
- TOPN(5, ALL(DimCustomer[CustomerName]), [Revenue], DESC)
211
- )
212
-
213
- Revenue Top 3 Stores =
214
- CALCULATE(
215
- [Revenue],
216
- TOPN(3, ALL(DimStore[StoreName]), [Revenue], DESC)
217
- )
218
-
219
- // Percentage of top 10 products
220
- Top 10 Products % =
221
- DIVIDE(
222
- [Revenue Top 10 Products],
223
- CALCULATE([Revenue], ALL(DimProduct))
224
- )
225
-
226
-
227
- // ----------------------------------------------------------------------------
228
- // PERCENTAGES & RATIOS
229
- // ----------------------------------------------------------------------------
230
-
231
- Revenue % of Total =
232
- DIVIDE(
233
- [Revenue],
234
- CALCULATE([Revenue], ALL(FactSales))
235
- )
236
-
237
- Revenue % of Category =
238
- DIVIDE(
239
- [Revenue],
240
- CALCULATE([Revenue], ALLEXCEPT(DimProduct, DimProduct[Category]))
241
- )
242
-
243
- Revenue % of Store =
244
- DIVIDE(
245
- [Revenue],
246
- CALCULATE([Revenue], ALLEXCEPT(DimStore, DimStore[StoreName]))
247
- )
248
-
249
- Revenue % of Region =
250
- DIVIDE(
251
- [Revenue],
252
- CALCULATE([Revenue], ALLEXCEPT(DimStore, DimStore[Region]))
253
- )
254
-
255
-
256
- // ----------------------------------------------------------------------------
257
- // CUSTOMER METRICS
258
- // ----------------------------------------------------------------------------
259
-
260
- Customer Count =
261
- DISTINCTCOUNT(FactSales[CustomerKey])
262
-
263
- New Customers =
264
- VAR _CurrentPeriodStart = MIN(DimDate[Date])
265
- RETURN
266
- CALCULATE(
267
- DISTINCTCOUNT(FactSales[CustomerKey]),
268
- FILTER(
269
- ALL(DimCustomer),
270
- DimCustomer[JoinDate] >= _CurrentPeriodStart
271
- )
272
- )
273
-
274
- Repeat Customers =
275
- VAR _CustomersThisPeriod = VALUES(FactSales[CustomerKey])
276
- VAR _CustomersWithHistory =
277
- FILTER(
278
- _CustomersThisPeriod,
279
- CALCULATE(
280
- COUNTROWS(FactSales),
281
- ALLEXCEPT(FactSales, FactSales[CustomerKey]),
282
- DimDate[Date] < MIN(DimDate[Date])
283
- ) > 0
284
- )
285
- RETURN
286
- COUNTROWS(_CustomersWithHistory)
287
-
288
- Revenue per Customer =
289
- DIVIDE([Revenue], [Customer Count])
290
-
291
-
292
- // ----------------------------------------------------------------------------
293
- // PRODUCT METRICS
294
- // ----------------------------------------------------------------------------
295
-
296
- Product Count =
297
- DISTINCTCOUNT(FactSales[ProductKey])
298
-
299
- Active Products =
300
- CALCULATE(
301
- DISTINCTCOUNT(DimProduct[ProductKey]),
302
- DimProduct[IsActive] = TRUE()
303
- )
304
-
305
- Units per Transaction =
306
- DIVIDE([Quantity], [Transactions])
307
-
308
- Basket Size =
309
- AVERAGEX(
310
- VALUES(FactSales[SalesKey]),
311
- CALCULATE(DISTINCTCOUNT(FactSales[ProductKey]))
312
- )
313
-
314
-
315
- // ----------------------------------------------------------------------------
316
- // STORE METRICS
317
- // ----------------------------------------------------------------------------
318
-
319
- Store Count =
320
- DISTINCTCOUNT(FactSales[StoreKey])
321
-
322
- Revenue per SqFt =
323
- DIVIDE(
324
- [Revenue],
325
- SUM(DimStore[SquareFeet])
326
- )
327
-
328
- Revenue per Employee =
329
- DIVIDE(
330
- [Revenue],
331
- SUM(DimStore[EmployeeCount])
332
- )
333
-
334
-
335
- // ----------------------------------------------------------------------------
336
- // CONDITIONAL FORMATTING MEASURES
337
- // ----------------------------------------------------------------------------
338
-
339
- Revenue YoY Color =
340
- VAR _YoY = [Revenue YoY %]
341
- RETURN
342
- SWITCH(
343
- TRUE(),
344
- ISBLANK(_YoY), "#A3A3A3", // Neutral gray
345
- _YoY >= 0.1, "#166534", // Dark green - exceeds 10%
346
- _YoY >= 0, "#22C55E", // Green - positive
347
- _YoY >= -0.1, "#EAB308", // Yellow - slightly down
348
- "#991B1B" // Dark red - down >10%
349
- )
350
-
351
- Profit Margin Color =
352
- VAR _Margin = [Profit Margin %]
353
- RETURN
354
- SWITCH(
355
- TRUE(),
356
- ISBLANK(_Margin), "#A3A3A3",
357
- _Margin >= 0.25, "#166534", // High margin
358
- _Margin >= 0.15, "#22C55E", // Target margin
359
- _Margin >= 0.10, "#EAB308", // Low margin
360
- "#991B1B" // Critical margin
361
- )
362
-
363
- Trend Indicator =
364
- VAR _YoY = [Revenue YoY %]
365
- RETURN
366
- SWITCH(
367
- TRUE(),
368
- ISBLANK(_YoY), "•",
369
- _YoY >= 0.1, "▲▲",
370
- _YoY >= 0, "▲",
371
- _YoY >= -0.1, "▼",
372
- "▼▼"
373
- )
374
-
375
-
376
- // ----------------------------------------------------------------------------
377
- // DISPLAY / HELPER MEASURES
378
- // ----------------------------------------------------------------------------
379
-
380
- Revenue Display =
381
- VAR _Value = [Revenue]
382
- RETURN
383
- IF(
384
- _Value >= 1000000,
385
- FORMAT(_Value / 1000000, "$#,##0.0") & "M",
386
- IF(
387
- _Value >= 1000,
388
- FORMAT(_Value / 1000, "$#,##0.0") & "K",
389
- FORMAT(_Value, "$#,##0")
390
- )
391
- )
392
-
393
- Revenue YoY Display =
394
- VAR _YoY = [Revenue YoY %]
395
- RETURN
396
- IF(
397
- ISBLANK(_YoY),
398
- "--",
399
- IF(_YoY >= 0, "+", "") & FORMAT(_YoY, "0.0%")
400
- )
401
-
402
- Selected Period =
403
- VAR _MinDate = MIN(DimDate[Date])
404
- VAR _MaxDate = MAX(DimDate[Date])
405
- RETURN
406
- FORMAT(_MinDate, "MMM D, YYYY") & " - " & FORMAT(_MaxDate, "MMM D, YYYY")
407
-
408
- Last Refresh =
409
- "Last updated: " & FORMAT(NOW(), "MMM D, YYYY h:mm AM/PM")
410
-
411
-
412
- // ----------------------------------------------------------------------------
413
- // DATA QUALITY CHECKS
414
- // ----------------------------------------------------------------------------
415
-
416
- _Data Quality Sales =
417
- VAR _TotalRows = COUNTROWS(FactSales)
418
- VAR _NullAmount = CALCULATE(COUNTROWS(FactSales), ISBLANK(FactSales[Amount]))
419
- VAR _NegativeAmount = CALCULATE(COUNTROWS(FactSales), FactSales[Amount] < 0)
420
- RETURN
421
- "Total: " & _TotalRows &
422
- " | Null Amounts: " & _NullAmount &
423
- " | Negative: " & _NegativeAmount
424
-
425
- _Missing Keys =
426
- VAR _OrphanProducts =
427
- COUNTROWS(
428
- FILTER(
429
- FactSales,
430
- ISBLANK(RELATED(DimProduct[ProductName]))
431
- )
432
- )
433
- VAR _OrphanCustomers =
434
- COUNTROWS(
435
- FILTER(
436
- FactSales,
437
- ISBLANK(RELATED(DimCustomer[CustomerName]))
438
- )
439
- )
440
- RETURN
441
- "Orphan Products: " & _OrphanProducts &
442
- " | Orphan Customers: " & _OrphanCustomers
443
-
444
-
445
- // ============================================================================
446
- // MEASURE ORGANIZATION
447
- // ============================================================================
448
- // Create Display Folders in Power BI:
449
- //
450
- // 📊 Base Metrics
451
- // - Revenue, Cost, Profit, Profit Margin %, Quantity, Transactions, AOV
452
- //
453
- // 📅 Time Intelligence
454
- // - YTD: Revenue YTD, Profit YTD, Quantity YTD
455
- // - Prior Year: Revenue PY, Profit PY, Revenue YTD PY
456
- // - Growth: Revenue YoY %, Revenue YoY Var, Profit YoY %, Revenue YTD YoY %
457
- // - Rolling: Revenue R3M, Revenue R12M, Revenue R3M Avg
458
- // - Month: Revenue PM, Revenue MoM %
459
- //
460
- // 🏆 Rankings
461
- // - Product Rank, Store Rank, Customer Rank, Category Rank
462
- //
463
- // 🎯 Top N
464
- // - Revenue Top 10 Products, Revenue Top 5 Customers, Revenue Top 3 Stores
465
- //
466
- // 📈 Percentages
467
- // - Revenue % of Total, Revenue % of Category, Revenue % of Store
468
- //
469
- // 👤 Customer
470
- // - Customer Count, New Customers, Repeat Customers, Revenue per Customer
471
- //
472
- // 🏪 Store
473
- // - Store Count, Revenue per SqFt, Revenue per Employee
474
- //
475
- // 🎨 Formatting
476
- // - Revenue YoY Color, Profit Margin Color, Trend Indicator
477
- //
478
- // 🔧 Helpers (Hidden)
479
- // - Revenue Display, Selected Period, Last Refresh
480
- // - _Data Quality Sales, _Missing Keys
481
- // ============================================================================
@@ -1,37 +0,0 @@
1
- # Supply Chain Analytics Example
2
-
3
- Reference implementation for a supply chain Power BI model.
4
-
5
- ## Business Context
6
-
7
- Track inventory levels, supplier performance, lead times, and fulfillment rates across warehouses and distribution centers.
8
-
9
- ## Key Metrics
10
-
11
- | Metric | Description |
12
- |--------|-------------|
13
- | Fill Rate | % of orders fulfilled completely |
14
- | Inventory Turnover | How often inventory is sold and replaced |
15
- | Days of Supply | Days of inventory remaining at current demand |
16
- | On-Time Delivery | % of orders delivered by promised date |
17
- | Supplier Lead Time | Average days from PO to receipt |
18
- | Stockout Rate | % of SKUs with zero inventory |
19
- | Carrying Cost | Cost to hold inventory per unit per period |
20
-
21
- ## Data Model
22
-
23
- See [data-model.md](data-model.md) for the complete star schema design.
24
-
25
- ## Files
26
-
27
- | File | Purpose |
28
- |------|---------|
29
- | `data-model.md` | Star schema with tables and relationships |
30
- | `measures.dax` | Core DAX measures for supply chain KPIs |
31
-
32
- ## Report Pages
33
-
34
- 1. **Executive Summary** — KPI cards, fill rate trend, top suppliers
35
- 2. **Inventory Health** — Stock levels by warehouse, days of supply heatmap
36
- 3. **Supplier Scorecard** — Lead time, quality, on-time delivery by supplier
37
- 4. **Demand vs Supply** — Forecast accuracy, stockout risk analysis
@@ -1,69 +0,0 @@
1
- # Supply Chain Data Model
2
-
3
- ## Star Schema
4
-
5
- ```
6
- ┌─────────────┐
7
- │ DimDate │
8
- │─────────────│
9
- │ DateKey (PK)│
10
- │ Date │
11
- │ Month │
12
- │ Quarter │
13
- │ Year │
14
- │ FiscalMonth │
15
- │ FiscalYear │
16
- └──────┬──────┘
17
-
18
- ┌─────────────┐ ┌───────┴───────┐ ┌──────────────┐
19
- │ DimSupplier │ │ FactInventory │ │ DimWarehouse │
20
- │─────────────│ │───────────────│ │──────────────│
21
- │ SupplierKey │◄───│ SupplierKey │───►│ WarehouseKey │
22
- │ SupplierName│ │ WarehouseKey │ │ WarehouseName│
23
- │ Country │ │ ProductKey │ │ Region │
24
- │ LeadTimeDays│ │ DateKey │ │ Capacity │
25
- │ Rating │ │ QuantityOnHand│ │ Type │
26
- └─────────────┘ │ QuantityOnOrder│ └──────────────┘
27
- │ ReorderPoint │
28
- ┌─────────────┐ │ UnitCost │ ┌──────────────┐
29
- │ DimProduct │ │ DaysOfSupply │ │ FactOrders │
30
- │─────────────│ └───────────────┘ │──────────────│
31
- │ ProductKey │◄────────────────────────│ ProductKey │
32
- │ ProductName │ │ │ CustomerKey │
33
- │ Category │ │ │ DateKey │
34
- │ SubCategory │ ▼ │ WarehouseKey │
35
- │ SKU │ ┌───────────────┐ │ Quantity │
36
- │ UnitWeight │ │FactPurchaseOrder│ │ ShipDate │
37
- │ IsActive │ │───────────────│ │ PromisedDate │
38
- └─────────────┘ │ POKey (PK) │ │ IsOnTime │
39
- │ SupplierKey │ │ IsFilled │
40
- │ ProductKey │ └──────────────┘
41
- │ DateKey │
42
- │ Quantity │
43
- │ UnitCost │
44
- │ ReceivedDate │
45
- │ LeadTimeDays │
46
- └───────────────┘
47
- ```
48
-
49
- ## Relationships
50
-
51
- | From | To | Cardinality | Direction |
52
- |------|----|-------------|-----------|
53
- | FactInventory[DateKey] | DimDate[DateKey] | Many-to-One | Single |
54
- | FactInventory[ProductKey] | DimProduct[ProductKey] | Many-to-One | Single |
55
- | FactInventory[SupplierKey] | DimSupplier[SupplierKey] | Many-to-One | Single |
56
- | FactInventory[WarehouseKey] | DimWarehouse[WarehouseKey] | Many-to-One | Single |
57
- | FactOrders[DateKey] | DimDate[DateKey] | Many-to-One | Single |
58
- | FactOrders[ProductKey] | DimProduct[ProductKey] | Many-to-One | Single |
59
- | FactOrders[WarehouseKey] | DimWarehouse[WarehouseKey] | Many-to-One | Single |
60
- | FactPurchaseOrder[DateKey] | DimDate[DateKey] | Many-to-One | Single |
61
- | FactPurchaseOrder[ProductKey] | DimProduct[ProductKey] | Many-to-One | Single |
62
- | FactPurchaseOrder[SupplierKey] | DimSupplier[SupplierKey] | Many-to-One | Single |
63
-
64
- ## Notes
65
-
66
- - `FactInventory` is a periodic snapshot (daily snapshot of stock levels)
67
- - `FactOrders` tracks customer orders and fulfillment
68
- - `FactPurchaseOrder` tracks supplier orders and lead times
69
- - `DaysOfSupply` in FactInventory is pre-calculated for performance
@@ -1,77 +0,0 @@
1
- // Supply Chain KPI Measures
2
- // ========================
3
- // Core measures for supply chain analytics model.
4
-
5
- // --- Inventory Metrics ---
6
-
7
- // Total units currently in stock across all warehouses
8
- TotalOnHand =
9
- SUM(FactInventory[QuantityOnHand])
10
-
11
- // Total units on order from suppliers
12
- TotalOnOrder =
13
- SUM(FactInventory[QuantityOnOrder])
14
-
15
- // Inventory turnover: how many times inventory is sold and replaced
16
- // Higher is better — indicates efficient inventory management
17
- InventoryTurnover =
18
- VAR _COGS = SUM(FactOrders[Quantity]) * AVERAGE(FactInventory[UnitCost])
19
- VAR _AvgInventory = AVERAGE(FactInventory[QuantityOnHand]) * AVERAGE(FactInventory[UnitCost])
20
- RETURN DIVIDE(_COGS, _AvgInventory)
21
-
22
- // Average days of supply remaining at current demand rate
23
- AvgDaysOfSupply =
24
- AVERAGE(FactInventory[DaysOfSupply])
25
-
26
- // Percentage of SKUs with zero inventory (stockout)
27
- StockoutRate =
28
- VAR _TotalSKUs = DISTINCTCOUNT(FactInventory[ProductKey])
29
- VAR _StockoutSKUs =
30
- CALCULATE(
31
- DISTINCTCOUNT(FactInventory[ProductKey]),
32
- FactInventory[QuantityOnHand] = 0
33
- )
34
- RETURN DIVIDE(_StockoutSKUs, _TotalSKUs)
35
-
36
- // --- Fulfillment Metrics ---
37
-
38
- // Fill rate: percentage of orders fulfilled completely
39
- FillRate =
40
- VAR _TotalOrders = COUNTROWS(FactOrders)
41
- VAR _FilledOrders = CALCULATE(COUNTROWS(FactOrders), FactOrders[IsFilled] = TRUE())
42
- RETURN DIVIDE(_FilledOrders, _TotalOrders)
43
-
44
- // On-time delivery rate
45
- OnTimeDeliveryRate =
46
- VAR _TotalOrders = COUNTROWS(FactOrders)
47
- VAR _OnTimeOrders = CALCULATE(COUNTROWS(FactOrders), FactOrders[IsOnTime] = TRUE())
48
- RETURN DIVIDE(_OnTimeOrders, _TotalOrders)
49
-
50
- // --- Supplier Metrics ---
51
-
52
- // Average supplier lead time in days
53
- AvgLeadTime =
54
- AVERAGE(FactPurchaseOrder[LeadTimeDays])
55
-
56
- // Supplier on-time rate (received by expected date)
57
- SupplierOnTimeRate =
58
- VAR _TotalPOs = COUNTROWS(FactPurchaseOrder)
59
- VAR _OnTimePOs =
60
- CALCULATE(
61
- COUNTROWS(FactPurchaseOrder),
62
- FactPurchaseOrder[LeadTimeDays] <= RELATED(DimSupplier[LeadTimeDays])
63
- )
64
- RETURN DIVIDE(_OnTimePOs, _TotalPOs)
65
-
66
- // --- Cost Metrics ---
67
-
68
- // Total inventory carrying cost (simplified: unitCost * quantity * holding rate)
69
- CarryingCost =
70
- SUMX(
71
- FactInventory,
72
- FactInventory[QuantityOnHand] * FactInventory[UnitCost] * 0.25 / 365
73
- )
74
-
75
- // Total purchase order value
76
- TotalPOValue =
77
- SUMX(FactPurchaseOrder, FactPurchaseOrder[Quantity] * FactPurchaseOrder[UnitCost])