From 45ca9ffb68ab2fd8fc7475de75aba8193c7a597a Mon Sep 17 00:00:00 2001 From: Bastien Gourdon Date: Mon, 27 Jul 2026 20:53:21 +0200 Subject: [PATCH] instances: alignement BR-013 de SODH, migration v1.1 terminee. 10 metriques meres, 132 data elements dont 95 computedBy et 37 represents, 15 concepts, 12 business objects. Grain sur les 4 dimensions seulement, celui des faits restant porte par references. Validation SHACL conforme, zero violation. Scripts rendus idempotents : des blocs dupliques sont invisibles a SHACL car les triplets identiques fusionnent --- instances/sodh.ttl | 1483 ++++++++++++++++++++++------- scripts/apply_arbitration_sodh.py | 23 +- scripts/apply_br013_sodh.py | 479 ++++++++++ scripts/run_shacl_validation.py | 32 +- 4 files changed, 1662 insertions(+), 355 deletions(-) create mode 100644 scripts/apply_br013_sodh.py diff --git a/instances/sodh.ttl b/instances/sodh.ttl index 8818533..e9ad9f0 100644 --- a/instances/sodh.ttl +++ b/instances/sodh.ttl @@ -164,13 +164,38 @@ ex:BC_21_01_001 a pr:BusinessConcept ; pr:arbitrationStatus "TO_ARBITRATE" ; pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain" . + +# --- concepts required by the meaning XOR --------------------------- +# Country, Marketing Entity and Fiscal Period had Data Elements but no +# notion behind them. The rule forced them to be named. +ex:BC_04_01_003 a pr:BusinessConcept ; + pr:hasIdentifier "BC-04.01-003" ; pr:hasName "Country" ; + pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; + pr:hasBusinessDefinition "A sovereign territory used as the geographic frame for retail measurement, identified by its ISO 3166 code. Distinct from Customer and Outlet: it is where they operate, not what they are." ; + pr:arbitrationStatus "TO_ARBITRATE" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain" . +ex:BC_16_01_003 a pr:BusinessConcept ; + pr:hasIdentifier "BC-16.01-003" ; pr:hasName "Marketing Entity" ; + pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; + pr:hasBusinessDefinition "An organisational unit of the group holding commercial responsibility for a market, and the level at which financial results are consolidated." ; + pr:arbitrationStatus "TO_ARBITRATE" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain" . +ex:BC_16_01_004 a pr:BusinessConcept ; + pr:hasIdentifier "BC-16.01-004" ; pr:hasName "Fiscal Period" ; + pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; + pr:hasBusinessDefinition "A reporting interval of the Pernod Ricard fiscal year, which runs July to June. Distinct from Calendar Date: the fiscal frame does not align with the Gregorian one." ; + pr:arbitrationStatus "TO_ARBITRATE" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain" . + ex:BO_06_01_001 a pr:BusinessObject ; pr:hasIdentifier "BO-06.01-001" ; pr:hasName "Sell Out Volume" ; pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; pr:belongsTo ex:SD_06_01 ; pr:monitoredBy ex:ST_DD_06 ; pr:aboutConcept ex:BC_06_01_001 ; pr:usesConcept ex:BC_06_01_003 , ex:BC_05_01_001 ; - pr:hasMetric ex:M_06_01_001 , ex:M_06_01_002 , ex:M_06_01_003 , ex:M_06_01_004 ; + pr:aboutConcept ex:BC_06_01_001 ; + pr:usesConcept ex:BC_06_01_003 , ex:BC_05_01_001 ; + pr:hasMetric ex:M_06_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / F_SELL_OUT" . ex:BO_06_01_002 a pr:BusinessObject ; pr:hasIdentifier "BO-06.01-002" ; pr:hasName "Sell Out Value" ; @@ -178,7 +203,9 @@ ex:BO_06_01_002 a pr:BusinessObject ; pr:belongsTo ex:SD_06_01 ; pr:monitoredBy ex:ST_DD_06 ; pr:aboutConcept ex:BC_06_01_001 ; pr:usesConcept ex:BC_06_01_003 , ex:BC_05_01_001 , ex:BC_16_01_001 ; - pr:hasMetric ex:M_06_01_010 , ex:M_06_01_011 , ex:M_06_01_012 ; + pr:aboutConcept ex:BC_06_01_001 ; + pr:usesConcept ex:BC_06_01_003 , ex:BC_05_01_001 , ex:BC_16_01_001 ; + pr:hasMetric ex:M_06_01_002 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / F_SELL_OUT" . ex:BO_06_01_003 a pr:BusinessObject ; pr:hasIdentifier "BO-06.01-003" ; pr:hasName "Sell Out Distribution" ; @@ -186,7 +213,9 @@ ex:BO_06_01_003 a pr:BusinessObject ; pr:belongsTo ex:SD_06_01 ; pr:monitoredBy ex:ST_DD_06 ; pr:aboutConcept ex:BC_06_01_004 ; pr:usesConcept ex:BC_06_01_003 ; - pr:hasMetric ex:M_06_01_020 , ex:M_06_01_021 , ex:M_06_01_022 ; + pr:aboutConcept ex:BC_06_01_004 ; + pr:usesConcept ex:BC_06_01_003 ; + pr:hasMetric ex:M_06_01_003 , ex:M_06_01_004 , ex:M_06_01_005 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / F_SELL_OUT_DISTRIBUTION" . ex:BO_06_01_004 a pr:BusinessObject ; pr:hasIdentifier "BO-06.01-004" ; pr:hasName "Retailer Stock" ; @@ -194,7 +223,9 @@ ex:BO_06_01_004 a pr:BusinessObject ; pr:belongsTo ex:SD_06_01 ; pr:monitoredBy ex:ST_DD_06 ; pr:aboutConcept ex:BC_06_01_002 ; pr:usesConcept ex:BC_06_01_001 , ex:BC_06_01_003 ; - pr:hasMetric ex:M_06_01_030 , ex:M_06_01_031 , ex:M_06_01_032 ; + pr:aboutConcept ex:BC_06_01_002 ; + pr:usesConcept ex:BC_06_01_001 , ex:BC_06_01_003 ; + pr:hasMetric ex:M_06_01_006 , ex:M_06_01_007 , ex:M_06_01_008 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / F_SELL_OUT" . ex:BO_06_01_005 a pr:BusinessObject ; pr:hasIdentifier "BO-06.01-005" ; pr:hasName "Sell Out Baseline" ; @@ -202,37 +233,44 @@ ex:BO_06_01_005 a pr:BusinessObject ; pr:belongsTo ex:SD_06_01 ; pr:monitoredBy ex:ST_DD_06 ; pr:aboutConcept ex:BC_06_01_005 ; pr:usesConcept ex:BC_06_01_001 , ex:BC_05_01_001 ; - pr:hasMetric ex:M_06_01_040 , ex:M_06_01_041 ; + pr:aboutConcept ex:BC_06_01_005 ; + pr:usesConcept ex:BC_06_01_001 , ex:BC_05_01_001 ; + pr:hasMetric ex:M_06_01_009 , ex:M_06_01_010 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / F_SELL_OUT_BASELINE" . ex:BO_10_01_001 a pr:BusinessObject ; pr:hasIdentifier "BO-10.01-001" ; pr:hasName "Product Structure" ; pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; pr:belongsTo ex:SD_10_01 ; pr:monitoredBy ex:ST_DD_10 ; pr:aboutConcept ex:BC_10_01_001 ; + pr:aboutConcept ex:BC_10_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product -> SODH [concepts TBC by DD-10]" . ex:BO_04_01_001 a pr:BusinessObject ; pr:hasIdentifier "BO-04.01-001" ; pr:hasName "Customer" ; pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; pr:belongsTo ex:SD_04_01 ; pr:monitoredBy ex:ST_DD_04 ; pr:aboutConcept ex:BC_04_01_001 ; + pr:aboutConcept ex:BC_04_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM -> SODH [split proposed, subject arbitrated 2026-07-27]" . ex:BO_16_01_001 a pr:BusinessObject ; pr:hasIdentifier "BO-16.01-001" ; pr:hasName "Currency" ; pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; pr:belongsTo ex:SD_16_01 ; pr:monitoredBy ex:ST_DD_16 ; pr:aboutConcept ex:BC_16_01_001 ; + pr:aboutConcept ex:BC_16_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM -> SODH [split proposed, subject arbitrated 2026-07-27]" . ex:BO_21_01_001 a pr:BusinessObject ; pr:hasIdentifier "BO-21.01-001" ; pr:hasName "Calendar" ; pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; pr:belongsTo ex:SD_21_01 ; pr:monitoredBy ex:ST_DD_21 ; pr:aboutConcept ex:BC_21_01_001 ; + pr:aboutConcept ex:BC_21_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Standard Calendar -> SODH [concepts TBC by DD-21]" . ex:BO_05_01_001 a pr:BusinessObject ; pr:hasIdentifier "BO-05.01-001" ; pr:hasName "Promotion Type" ; pr:owningDomain ex:DD_05 ; pr:ownedBy ex:ST_DD_05 ; pr:belongsTo ex:SD_05_01 ; pr:monitoredBy ex:ST_DD_05 ; pr:aboutConcept ex:BC_05_01_001 ; + pr:aboutConcept ex:BC_05_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Sales Activation -> SODH [concepts TBC by DD-05]" . @@ -254,371 +292,1122 @@ ex:BO_16_01_002 a pr:BusinessObject ; pr:arbitrationStatus "TO_ARBITRATE" ; pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance -> SODH [split from BO-16.01-001, proposed to DD-16]" . -ex:M_06_01_001 a pr:Metric ; - pr:hasIdentifier "M-06.01-001" ; pr:hasName "Sell Out Volume (9L)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "SUM(GL_VOLUME_9L_NM)" ; pr:hasUnit "9L" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_VOLUME_9L_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_VOLUME_9L_NM" . -ex:M_06_01_002 a pr:Metric ; - pr:hasIdentifier "M-06.01-002" ; pr:hasName "Sell Out Volume (L)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "SUM(GL_VOLUME_L_NM)" ; pr:hasUnit "L" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_VOLUME_L_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_VOLUME_L_NM" . -ex:M_06_01_003 a pr:Metric ; - pr:hasIdentifier "M-06.01-003" ; pr:hasName "Sell Out Volume Non-Promoted (L)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "SUM(GL_VOLUME_L_NO_PROMO_NM)" ; pr:hasUnit "L" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_VOLUME_L_NO_PROMO_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_VOLUME_L_NO_PROMO_NM" . -ex:M_06_01_004 a pr:Metric ; - pr:hasIdentifier "M-06.01-004" ; pr:hasName "Sell Out Volume Promoted (L)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "SUM(GL_VOLUME_L_ANY_PROMO_NM)" ; pr:hasUnit "L" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_VOLUME_L_ANY_PROMO_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_VOLUME_L_ANY_PROMO_NM" . -ex:M_06_01_010 a pr:Metric ; - pr:hasIdentifier "M-06.01-010" ; pr:hasName "Sell Out Value (EUR)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "SUM(GL_VALUE_EUR_NM)" ; pr:hasUnit "EUR" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_VALUE_EUR_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_VALUE_EUR_NM" . -ex:M_06_01_011 a pr:Metric ; - pr:hasIdentifier "M-06.01-011" ; pr:hasName "Sell Out Value (LC)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "SUM(GL_VALUE_LC_NM)" ; pr:hasUnit "LC" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_VALUE_LC_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_VALUE_LC_NM" . -ex:M_06_01_012 a pr:Metric ; - pr:hasIdentifier "M-06.01-012" ; pr:hasName "Sell Out Value (USD)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "SUM(GL_VALUE_USD_NM)" ; pr:hasUnit "USD" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_VALUE_USD_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_VALUE_USD_NM" . -ex:M_06_01_020 a pr:Metric ; - pr:hasIdentifier "M-06.01-020" ; pr:hasName "Sell Out Numeric Distribution (%)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_004 ; - pr:hasFormula "COUNT(outlets carrying SKU) / COUNT(universe outlets) * 100" ; pr:hasUnit "%" ; pr:hasGranularity "SKU x Country x Period" ; - pr:physicalName "GL_NUMERIC_DISTRIBUTION_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_NUMERIC_DISTRIBUTION_NM" . -ex:M_06_01_021 a pr:Metric ; - pr:hasIdentifier "M-06.01-021" ; pr:hasName "Sell Out Weighted Distribution (%)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_004 ; - pr:hasFormula "SUM(cat. turnover of outlets carrying SKU) / SUM(total cat. turnover) * 100" ; pr:hasUnit "%" ; pr:hasGranularity "SKU x Country x Period" ; - pr:physicalName "GL_WEIGHTED_DISTRIBUTION_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_WEIGHTED_DISTRIBUTION_NM" . -ex:M_06_01_022 a pr:Metric ; - pr:hasIdentifier "M-06.01-022" ; pr:hasName "Sell Out Total Distribution Points (Index)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_004 ; - pr:hasFormula "SUM(Weighted Distribution across SKUs of the brand)" ; pr:hasUnit "Index" ; pr:hasGranularity "Brand x Country x Period" ; - pr:physicalName "GL_TDP_NM" ; - pr:hasAcronym "TDP" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_TDP_NM" . -ex:M_06_01_030 a pr:Metric ; - pr:hasIdentifier "M-06.01-030" ; pr:hasName "Retailer Stock Forward Volume (L)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_002 ; - pr:hasFormula "SUM(GL_STOCK_FORWARD_VOLUME_L_NM)" ; pr:hasUnit "L" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_STOCK_FORWARD_VOLUME_L_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_STOCK_FORWARD_VOLUME_L_NM" . -ex:M_06_01_031 a pr:Metric ; - pr:hasIdentifier "M-06.01-031" ; pr:hasName "Retailer Stock Days of Coverage (Days)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_002 ; - pr:hasFormula "Retailer Forward Stock Volume / avg daily Sell Out Volume" ; pr:hasUnit "Days" ; pr:hasGranularity "SKU x Customer x Day" ; - pr:physicalName "GL_DAYS_IN_COVERAGE" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_DAYS_IN_COVERAGE" . -ex:M_06_01_032 a pr:Metric ; - pr:hasIdentifier "M-06.01-032" ; pr:hasName "Retailer Stock Share by-SKU (%)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_002 ; - pr:hasFormula "SKU retailer stock / category retailer stock * 100" ; pr:hasUnit "%" ; pr:hasGranularity "SKU x Category x Period" ; - pr:physicalName "GL_SHARES_OF_FORWARD_STOCK_VOLUME_9L_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_SHARES_OF_FORWARD_STOCK_VOLUME_9L_NM" . -ex:M_06_01_040 a pr:Metric ; - pr:hasIdentifier "M-06.01-040" ; pr:hasName "Sell Out Baseline Volume Modelled (9L)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "MODEL(no-promo scenario volume)" ; pr:hasUnit "9L" ; pr:hasGranularity "SKU x Customer x Week" ; - pr:physicalName "GL_BASELINE_VOLUME_9L_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_BASELINE_VOLUME_9L_NM" . -ex:M_06_01_041 a pr:Metric ; - pr:hasIdentifier "M-06.01-041" ; pr:hasName "Sell Out Incremental Volume vs-Baseline (9L)" ; - pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:measures ex:BC_06_01_001 ; - pr:hasFormula "Observed Volume - Baseline Volume" ; pr:hasUnit "9L" ; pr:hasGranularity "SKU x Customer x Week" ; - pr:physicalName "GL_INCREMENTAL_VOLUME_9L_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / GL_INCREMENTAL_VOLUME_9L_NM" . - -ex:DE_10_01_0001 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0001" ; pr:hasName "Brand Code" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(10)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "BRAND_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / BRAND_CD" . -ex:DE_10_01_0002 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0002" ; pr:hasName "Brand Name" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(100)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "BRAND_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / BRAND_NM" . -ex:DE_10_01_0003 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0003" ; pr:hasName "Product Category" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(50)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "CATEGORY_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / CATEGORY_NM" . -ex:DE_10_01_0004 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0004" ; pr:hasName "Product Sub-Category" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(50)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "SUB_CATEGORY_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / SUB_CATEGORY_NM" . -ex:DE_10_01_0005 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0005" ; pr:hasName "SKU Code" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(20)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "SKU_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / SKU_CD" . -ex:DE_10_01_0006 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0006" ; pr:hasName "SKU Description" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(255)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "SKU_DESC" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / SKU_DESC" . -ex:DE_10_01_0007 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0007" ; pr:hasName "Bottle Size (mL)" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "INTEGER" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "BOTTLE_SIZE_ML" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / BOTTLE_SIZE_ML" . -ex:DE_10_01_0008 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0008" ; pr:hasName "Pack Size (Count)" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "INTEGER" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "PACK_SIZE_NR" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / PACK_SIZE_NR" . -ex:DE_10_01_0009 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0009" ; pr:hasName "Flavor" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(50)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "FLAVOR_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / FLAVOR_NM" . -ex:DE_10_01_0010 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0010" ; pr:hasName "Innovation Flag" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "BOOLEAN" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "INNOVATION_FLG" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / INNOVATION_FLG" . -ex:DE_10_01_0011 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0011" ; pr:hasName "Strategic Priority Flag" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "BOOLEAN" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "STRATEGIC_PRIORITY_FLG" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / STRATEGIC_PRIORITY_FLG" . -ex:DE_10_01_0012 a pr:DataElement ; - pr:hasIdentifier "DE-10.01-0012" ; pr:hasName "Unit of Measure Standard" ; - pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:hasFormat "STRING(10)" ; pr:hasSourceSystem "MDM Product" ; - pr:physicalName "UOM_STANDARD_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Product / UOM_STANDARD_CD" . -ex:DE_04_01_0001 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0001" ; pr:hasName "Distributor Code" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(20)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "DISTRIBUTOR_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / DISTRIBUTOR_CD" . -ex:DE_04_01_0002 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0002" ; pr:hasName "Distributor Name" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(150)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "DISTRIBUTOR_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / DISTRIBUTOR_NM" . -ex:DE_04_01_0003 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0003" ; pr:hasName "Distributor Branch Code" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(20)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "DISTRIBUTOR_BRANCH_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / DISTRIBUTOR_BRANCH_CD" . -ex:DE_04_01_0004 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0004" ; pr:hasName "Customer Tier-1 Code" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(20)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "CUSTOMER_T1_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / CUSTOMER_T1_CD" . -ex:DE_04_01_0005 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0005" ; pr:hasName "Customer Tier-2 Code" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(20)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "CUSTOMER_T2_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / CUSTOMER_T2_CD" . -ex:DE_04_01_0006 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0006" ; pr:hasName "Outlet Type" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(30)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "OUTLET_TYPE_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / OUTLET_TYPE_NM" . -ex:DE_04_01_0007 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0007" ; pr:hasName "Channel" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(30)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "CHANNEL_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / CHANNEL_NM" . -ex:DE_04_01_0008 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0008" ; pr:hasName "Country Code" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(2)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "COUNTRY_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / COUNTRY_CD" . -ex:DE_04_01_0009 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0009" ; pr:hasName "Country Name" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "STRING(100)" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "COUNTRY_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / COUNTRY_NM" . -ex:DE_04_01_0010 a pr:DataElement ; - pr:hasIdentifier "DE-04.01-0010" ; pr:hasName "Point of Sale Count (Count)" ; - pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:hasFormat "INTEGER" ; pr:hasSourceSystem "MDM Customer" ; - pr:physicalName "POS_COUNT_NR" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "MDM Customer / POS_COUNT_NR" . -ex:DE_16_01_0001 a pr:DataElement ; - pr:hasIdentifier "DE-16.01-0001" ; pr:hasName "Currency Code" ; - pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; - pr:hasFormat "STRING(3)" ; pr:hasSourceSystem "Group Finance" ; - pr:physicalName "CURRENCY_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Group Finance / CURRENCY_CD" . -ex:DE_16_01_0002 a pr:DataElement ; - pr:hasIdentifier "DE-16.01-0002" ; pr:hasName "FX Rate to-Euro (Rate)" ; - pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; - pr:hasFormat "DECIMAL(18,8)" ; pr:hasSourceSystem "Group Finance" ; - pr:physicalName "FX_RATE_TO_EUR" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Group Finance / FX_RATE_TO_EUR" . -ex:DE_16_01_0003 a pr:DataElement ; - pr:hasIdentifier "DE-16.01-0003" ; pr:hasName "FX Rate to-USD (Rate)" ; - pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; - pr:hasFormat "DECIMAL(18,8)" ; pr:hasSourceSystem "Group Finance" ; - pr:physicalName "FX_RATE_TO_USD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Group Finance / FX_RATE_TO_USD" . -ex:DE_16_02_0001 a pr:DataElement ; - pr:hasIdentifier "DE-16.02-0001" ; pr:hasName "Marketing Entity Code" ; - pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; - pr:hasFormat "STRING(10)" ; pr:hasSourceSystem "Group Finance" ; - pr:physicalName "MARKETING_ENTITY_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Group Finance / MARKETING_ENTITY_CD" . -ex:DE_16_02_0002 a pr:DataElement ; - pr:hasIdentifier "DE-16.02-0002" ; pr:hasName "Fiscal Period Code" ; - pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; - pr:hasFormat "STRING(10)" ; pr:hasSourceSystem "Group Finance" ; - pr:physicalName "PR_FISCAL_PERIOD_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Group Finance / PR_FISCAL_PERIOD_CD" . -ex:DE_16_02_0003 a pr:DataElement ; - pr:hasIdentifier "DE-16.02-0003" ; pr:hasName "Fiscal Quarter Code" ; - pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; - pr:hasFormat "STRING(10)" ; pr:hasSourceSystem "Group Finance" ; - pr:physicalName "PR_FISCAL_QUARTER_CD" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Group Finance / PR_FISCAL_QUARTER_CD" . -ex:DE_21_01_0001 a pr:DataElement ; - pr:hasIdentifier "DE-21.01-0001" ; pr:hasName "Calendar Date" ; - pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; - pr:hasFormat "DATE" ; pr:hasSourceSystem "Standard Calendar" ; - pr:physicalName "DATE_DT" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Standard Calendar / DATE_DT" . -ex:DE_21_01_0002 a pr:DataElement ; - pr:hasIdentifier "DE-21.01-0002" ; pr:hasName "Day of Week Name" ; - pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; - pr:hasFormat "STRING(10)" ; pr:hasSourceSystem "Standard Calendar" ; - pr:physicalName "DAY_OF_WEEK_NM" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Standard Calendar / DAY_OF_WEEK_NM" . -ex:DE_21_01_0003 a pr:DataElement ; - pr:hasIdentifier "DE-21.01-0003" ; pr:hasName "ISO Week Number (Count)" ; - pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; - pr:hasFormat "INTEGER" ; pr:hasSourceSystem "Standard Calendar" ; - pr:physicalName "ISO_WEEK_NR" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Standard Calendar / ISO_WEEK_NR" . -ex:DE_21_01_0004 a pr:DataElement ; - pr:hasIdentifier "DE-21.01-0004" ; pr:hasName "Month Number (Count)" ; - pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; - pr:hasFormat "INTEGER" ; pr:hasSourceSystem "Standard Calendar" ; - pr:physicalName "MONTH_NR" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Standard Calendar / MONTH_NR" . -ex:DE_21_01_0005 a pr:DataElement ; - pr:hasIdentifier "DE-21.01-0005" ; pr:hasName "Public Holiday Flag" ; - pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; - pr:hasFormat "BOOLEAN" ; pr:hasSourceSystem "Standard Calendar" ; - pr:physicalName "PUBLIC_HOLIDAY_FLG" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "Standard Calendar / PUBLIC_HOLIDAY_FLG" . -ex:DE_05_01_0001 a pr:DataElement ; - pr:hasIdentifier "DE-05.01-0001" ; pr:hasName "Promotion Type Temporary Price Reduction Flag" ; - pr:owningDomain ex:DD_05 ; pr:ownedBy ex:ST_DD_05 ; - pr:hasFormat "BOOLEAN" ; pr:hasSourceSystem "SODH Gold (flag)" ; - pr:physicalName "GL_PROMO_TPR_FLG" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold (flag) / GL_PROMO_TPR_FLG" . -ex:DE_05_01_0002 a pr:DataElement ; - pr:hasIdentifier "DE-05.01-0002" ; pr:hasName "Promotion Type Multibuy Flag" ; - pr:owningDomain ex:DD_05 ; pr:ownedBy ex:ST_DD_05 ; - pr:hasFormat "BOOLEAN" ; pr:hasSourceSystem "SODH Gold (flag)" ; - pr:physicalName "GL_PROMO_MULTIBUY_FLG" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold (flag) / GL_PROMO_MULTIBUY_FLG" . -ex:DE_05_01_0003 a pr:DataElement ; - pr:hasIdentifier "DE-05.01-0003" ; pr:hasName "Promotion Type Feature Display Flag" ; - pr:owningDomain ex:DD_05 ; pr:ownedBy ex:ST_DD_05 ; - pr:hasFormat "BOOLEAN" ; pr:hasSourceSystem "SODH Gold (flag)" ; - pr:physicalName "GL_PROMO_FEATURE_DISPLAY_FLG" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold (flag) / GL_PROMO_FEATURE_DISPLAY_FLG" . -ex:DE_05_01_0004 a pr:DataElement ; - pr:hasIdentifier "DE-05.01-0004" ; pr:hasName "Promotion Type Brochure Flag" ; - pr:owningDomain ex:DD_05 ; pr:ownedBy ex:ST_DD_05 ; - pr:hasFormat "BOOLEAN" ; pr:hasSourceSystem "SODH Gold (flag)" ; - pr:physicalName "GL_PROMO_BROCHURE_FLG" ; - pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold (flag) / GL_PROMO_BROCHURE_FLG" . - ex:DO_06_01_001 a pr:DataObject ; pr:hasIdentifier "DO-06.01-001" ; pr:hasName "Sell Out Volume Dataset" ; pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:represents ex:BO_06_01_001 ; pr:monitoredBy ex:ST_DD_06 ; - pr:hasElement ex:DE_05_01_0001 , ex:DE_05_01_0002 , ex:DE_05_01_0003 , ex:DE_05_01_0004 ; + pr:represents ex:BO_06_01_001 ; + pr:hasElement ex:DE_06_01_0001 , ex:DE_06_01_0002 , ex:DE_06_01_0003 , ex:DE_06_01_0004 , + ex:DE_06_01_0005 , ex:DE_06_01_0006 , ex:DE_06_01_0007 , ex:DE_06_01_0008 , + ex:DE_06_01_0009 , ex:DE_06_01_0010 , ex:DE_06_01_0011 , ex:DE_06_01_0012 , + ex:DE_06_01_0013 , ex:DE_06_01_0014 , ex:DE_06_01_0015 , ex:DE_06_01_0016 , + ex:DE_06_01_0017 , ex:DE_06_01_0018 , ex:DE_06_01_0019 , ex:DE_06_01_0020 , + ex:DE_06_01_0021 , ex:DE_06_01_0022 , ex:DE_06_01_0023 , ex:DE_06_01_0024 , + ex:DE_06_01_0025 , ex:DE_06_01_0026 , ex:DE_06_01_0027 , ex:DE_06_01_0028 , + ex:DE_06_01_0029 , ex:DE_06_01_0030 , ex:DE_06_01_0031 , ex:DE_06_01_0032 , + ex:DE_06_01_0033 , ex:DE_06_01_0034 , ex:DE_06_01_0035 , ex:DE_06_01_0036 , + ex:DE_06_01_0037 , ex:DE_06_01_0038 , ex:DE_06_01_0039 , ex:DE_06_01_0040 , + ex:DE_06_01_0041 , ex:DE_06_01_0042 , ex:DE_06_01_0043 , ex:DE_06_01_0044 , + ex:DE_06_01_0045 , ex:DE_06_01_0046 , ex:DE_06_01_0047 , ex:DE_06_01_0048 , + ex:DE_06_01_0049 , ex:DE_06_01_0050 , ex:DE_06_01_0051 , ex:DE_06_01_0052 , + ex:DE_06_01_0053 , ex:DE_06_01_0054 , ex:DE_06_01_0055 , ex:DE_06_01_0056 , + ex:DE_06_01_0057 , ex:DE_06_01_0058 , ex:DE_06_01_0059 , ex:DE_06_01_0060 , + ex:DE_06_01_0076 , ex:DE_06_01_0077 , ex:DE_06_01_0078 , ex:DE_06_01_0079 , + ex:DE_06_01_0080 , ex:DE_06_01_0081 , ex:DE_06_01_0082 , ex:DE_06_01_0083 , + ex:DE_06_01_0084 , ex:DE_06_01_0085 , ex:DE_06_01_0086 , ex:DE_06_01_0087 , + ex:DE_06_01_0088 , ex:DE_06_01_0089 , ex:DE_06_01_0090 , ex:DE_06_01_0091 , + ex:DE_06_01_0092 , ex:DE_06_01_0093 , ex:DE_06_01_0094 , ex:DE_06_01_0095 , + ex:DE_05_01_0001 , ex:DE_05_01_0002 , ex:DE_05_01_0003 , ex:DE_05_01_0004 ; pr:references ex:DO_04_01_001 , ex:DO_10_01_001 , ex:DO_21_01_001 , ex:DO_16_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / F_SELL_OUT" . ex:DO_06_01_003 a pr:DataObject ; pr:hasIdentifier "DO-06.01-003" ; pr:hasName "Sell Out Distribution Dataset" ; pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; - pr:represents ex:BO_06_01_003 ; pr:monitoredBy ex:ST_DD_06 ; - pr:hasElement ex:DE_05_01_0001 , ex:DE_05_01_0002 , ex:DE_05_01_0003 , ex:DE_05_01_0004 ; + pr:represents ex:BO_06_01_003 ; + pr:hasElement ex:DE_06_01_0061 , ex:DE_06_01_0062 , ex:DE_06_01_0063 , ex:DE_06_01_0064 , + ex:DE_06_01_0065 , ex:DE_06_01_0066 , ex:DE_06_01_0067 , ex:DE_06_01_0068 , + ex:DE_06_01_0069 , ex:DE_06_01_0070 , ex:DE_06_01_0071 , ex:DE_06_01_0072 , + ex:DE_06_01_0073 , ex:DE_06_01_0074 , ex:DE_06_01_0075 ; pr:references ex:DO_04_01_001 , ex:DO_10_01_001 , ex:DO_21_01_001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / F_SELL_OUT_DISTRIBUTION" . ex:DO_10_01_001 a pr:DataObject ; pr:hasIdentifier "DO-10.01-001" ; pr:hasName "Product Dimension" ; pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; - pr:represents ex:BO_10_01_001 ; pr:monitoredBy ex:ST_DD_10 ; - pr:hasElement ex:DE_10_01_0001 , ex:DE_10_01_0002 , ex:DE_10_01_0003 , ex:DE_10_01_0004 , ex:DE_10_01_0005 , ex:DE_10_01_0006 , ex:DE_10_01_0007 , ex:DE_10_01_0008 , ex:DE_10_01_0009 , ex:DE_10_01_0010 , ex:DE_10_01_0011 , ex:DE_10_01_0012 ; + pr:represents ex:BO_10_01_001 ; + pr:hasElement ex:DE_10_01_0001 , ex:DE_10_01_0002 , ex:DE_10_01_0003 , ex:DE_10_01_0004 , + ex:DE_10_01_0005 , ex:DE_10_01_0006 , ex:DE_10_01_0007 , ex:DE_10_01_0008 , + ex:DE_10_01_0009 , ex:DE_10_01_0010 , ex:DE_10_01_0011 , ex:DE_10_01_0012 ; + pr:hasGrainElement ex:DE_10_01_0005 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / D_FINISHED_PRODUCT" . ex:DO_04_01_001 a pr:DataObject ; pr:hasIdentifier "DO-04.01-001" ; pr:hasName "Customer Dimension" ; pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; - pr:represents ex:BO_04_01_001 ; pr:monitoredBy ex:ST_DD_04 ; - pr:hasElement ex:DE_04_01_0001 , ex:DE_04_01_0002 , ex:DE_04_01_0003 , ex:DE_04_01_0004 , ex:DE_04_01_0005 , ex:DE_04_01_0006 , ex:DE_04_01_0007 , ex:DE_04_01_0008 , ex:DE_04_01_0009 , ex:DE_04_01_0010 ; + pr:represents ex:BO_04_01_001 ; + pr:hasElement ex:DE_04_01_0001 , ex:DE_04_01_0002 , ex:DE_04_01_0003 , ex:DE_04_01_0004 , + ex:DE_04_01_0005 , ex:DE_04_01_0006 , ex:DE_04_01_0007 , ex:DE_04_01_0008 , + ex:DE_04_01_0009 , ex:DE_04_01_0010 ; + pr:hasGrainElement ex:DE_04_01_0005 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / D_CUSTOMER" . ex:DO_16_01_001 a pr:DataObject ; pr:hasIdentifier "DO-16.01-001" ; pr:hasName "Currency Dimension" ; pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; - pr:represents ex:BO_16_01_001 ; pr:monitoredBy ex:ST_DD_16 ; - pr:hasElement ex:DE_16_01_0001 , ex:DE_16_01_0002 , ex:DE_16_01_0003 , ex:DE_16_02_0001 , ex:DE_16_02_0002 , ex:DE_16_02_0003 ; + pr:represents ex:BO_16_01_001 ; + pr:hasElement ex:DE_16_01_0001 , ex:DE_16_01_0002 , ex:DE_16_01_0003 , ex:DE_16_02_0001 , + ex:DE_16_02_0002 , ex:DE_16_02_0003 ; + pr:hasGrainElement ex:DE_16_01_0001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / D_CURRENCY" . ex:DO_21_01_001 a pr:DataObject ; pr:hasIdentifier "DO-21.01-001" ; pr:hasName "Calendar Dimension" ; pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; - pr:represents ex:BO_21_01_001 ; pr:monitoredBy ex:ST_DD_21 ; - pr:hasElement ex:DE_21_01_0001 , ex:DE_21_01_0002 , ex:DE_21_01_0003 , ex:DE_21_01_0004 , ex:DE_21_01_0005 ; + pr:represents ex:BO_21_01_001 ; + pr:hasElement ex:DE_21_01_0001 , ex:DE_21_01_0002 , ex:DE_21_01_0003 , ex:DE_21_01_0004 , + ex:DE_21_01_0005 ; + pr:hasGrainElement ex:DE_21_01_0001 ; pr:hasStatus "DRAFT" ; pr:hasVersion "0.6" ; pr:hasSource "SODH Gold / D_DATE" . + + +# --- mother metrics, BR-013 ----------------------------------------- +# One harmonized calculation rule each. The granular variants are Data +# Elements linked by computedBy. No physical name (layer leak) and no +# granularity (a calculation rule has no rows). + +ex:M_06_01_001 a pr:Metric ; + pr:hasIdentifier "M-06.01-001" ; pr:hasName "Sell Out Volume" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "SUM(validated sell-out volumes over the period)" ; + pr:hasUnit "9L" ; + pr:measures ex:BC_06_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_002 a pr:Metric ; + pr:hasIdentifier "M-06.01-002" ; pr:hasName "Sell Out Value" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "SUM(validated sell-out value over the period)" ; + pr:hasUnit "EUR" ; + pr:measures ex:BC_06_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_003 a pr:Metric ; + pr:hasIdentifier "M-06.01-003" ; pr:hasName "Sell Out Numeric Distribution" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "COUNT(outlets carrying the SKU) / COUNT(universe outlets) * 100" ; + pr:hasUnit "%" ; + pr:measures ex:BC_06_01_004 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_004 a pr:Metric ; + pr:hasIdentifier "M-06.01-004" ; pr:hasName "Sell Out Weighted Distribution" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "SUM(category turnover of outlets carrying SKU) / SUM(total category turnover) * 100" ; + pr:hasUnit "%" ; + pr:measures ex:BC_06_01_004 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_005 a pr:Metric ; + pr:hasIdentifier "M-06.01-005" ; pr:hasName "Sell Out Total Distribution Points" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "SUM(Weighted Distribution across SKUs of the brand)" ; + pr:hasUnit "Index" ; + pr:measures ex:BC_06_01_004 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_006 a pr:Metric ; + pr:hasIdentifier "M-06.01-006" ; pr:hasName "Retailer Stock Forward Volume" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "SUM(retailer forward stock volume at period end)" ; + pr:hasUnit "9L" ; + pr:measures ex:BC_06_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_007 a pr:Metric ; + pr:hasIdentifier "M-06.01-007" ; pr:hasName "Retailer Stock Days of Coverage" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "Retailer Forward Stock Volume / average daily Sell Out Volume" ; + pr:hasUnit "Days" ; + pr:measures ex:BC_06_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_008 a pr:Metric ; + pr:hasIdentifier "M-06.01-008" ; pr:hasName "Retailer Stock Share" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "SKU retailer stock / category retailer stock * 100" ; + pr:hasUnit "%" ; + pr:measures ex:BC_06_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_009 a pr:Metric ; + pr:hasIdentifier "M-06.01-009" ; pr:hasName "Sell Out Baseline Volume Modelled" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "MODEL(expected volume under a no-promotion scenario)" ; + pr:hasUnit "9L" ; + pr:measures ex:BC_06_01_005 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . +ex:M_06_01_010 a pr:Metric ; + pr:hasIdentifier "M-06.01-010" ; pr:hasName "Sell Out Incremental Volume Modelled" ; + pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ; + pr:hasFormula "Observed Sell Out Volume - Baseline Volume" ; + pr:hasUnit "9L" ; + pr:measures ex:BC_06_01_005 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH back-doc v0.7" . + +# --- dimensional data elements -------------------------------------- +# Each represents the Concept it carries: the first of the two routes +# to business meaning. + +ex:DE_10_01_0001 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0001" ; pr:hasName "Brand Code" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(10)" ; + pr:physicalName "BRAND_CD" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0002 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0002" ; pr:hasName "Brand Name" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(100)" ; + pr:physicalName "BRAND_NM" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0003 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0003" ; pr:hasName "Product Category" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(50)" ; + pr:physicalName "CATEGORY_NM" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0004 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0004" ; pr:hasName "Product Sub-Category" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(50)" ; + pr:physicalName "SUB_CATEGORY_NM" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0005 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0005" ; pr:hasName "SKU Code" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(20)" ; + pr:physicalName "SKU_CD" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0006 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0006" ; pr:hasName "SKU Description" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(255)" ; + pr:physicalName "SKU_DESC" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0007 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0007" ; pr:hasName "Bottle Size (mL)" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "INTEGER" ; + pr:hasUnit "mL" ; + pr:physicalName "BOTTLE_SIZE_ML" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0008 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0008" ; pr:hasName "Pack Size (Count)" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "INTEGER" ; + pr:hasUnit "Count" ; + pr:physicalName "PACK_SIZE_NR" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0009 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0009" ; pr:hasName "Flavor" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(50)" ; + pr:physicalName "FLAVOR_NM" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0010 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0010" ; pr:hasName "Innovation Flag" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "BOOLEAN" ; + pr:physicalName "INNOVATION_FLG" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0011 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0011" ; pr:hasName "Strategic Priority Flag" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "BOOLEAN" ; + pr:physicalName "STRATEGIC_PRIORITY_FLG" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_10_01_0012 a pr:DataElement ; + pr:hasIdentifier "DE-10.01-0012" ; pr:hasName "Unit of Measure Standard" ; + pr:owningDomain ex:DD_10 ; + pr:hasFormat "STRING(10)" ; + pr:physicalName "UOM_STANDARD_CD" ; + pr:represents ex:BC_10_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Product" . +ex:DE_04_01_0001 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0001" ; pr:hasName "Distributor Code" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(20)" ; + pr:physicalName "DISTRIBUTOR_CD" ; + pr:represents ex:BC_04_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0002 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0002" ; pr:hasName "Distributor Name" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(150)" ; + pr:physicalName "DISTRIBUTOR_NM" ; + pr:represents ex:BC_04_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0003 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0003" ; pr:hasName "Distributor Branch Code" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(20)" ; + pr:physicalName "DISTRIBUTOR_BRANCH_CD" ; + pr:represents ex:BC_04_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0004 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0004" ; pr:hasName "Customer Tier-1 Code" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(20)" ; + pr:physicalName "CUSTOMER_T1_CD" ; + pr:represents ex:BC_04_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0005 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0005" ; pr:hasName "Customer Tier-2 Code" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(20)" ; + pr:physicalName "CUSTOMER_T2_CD" ; + pr:represents ex:BC_04_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0006 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0006" ; pr:hasName "Outlet Type" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(30)" ; + pr:physicalName "OUTLET_TYPE_NM" ; + pr:represents ex:BC_04_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0007 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0007" ; pr:hasName "Channel" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(30)" ; + pr:physicalName "CHANNEL_NM" ; + pr:represents ex:BC_04_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0008 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0008" ; pr:hasName "Country Code" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(2)" ; + pr:physicalName "COUNTRY_CD" ; + pr:represents ex:BC_04_01_003 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0009 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0009" ; pr:hasName "Country Name" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "STRING(100)" ; + pr:physicalName "COUNTRY_NM" ; + pr:represents ex:BC_04_01_003 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_04_01_0010 a pr:DataElement ; + pr:hasIdentifier "DE-04.01-0010" ; pr:hasName "Point of Sale Count (Count)" ; + pr:owningDomain ex:DD_04 ; + pr:hasFormat "INTEGER" ; + pr:hasUnit "Count" ; + pr:physicalName "POS_COUNT_NR" ; + pr:represents ex:BC_04_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer" . +ex:DE_16_01_0001 a pr:DataElement ; + pr:hasIdentifier "DE-16.01-0001" ; pr:hasName "Currency Code" ; + pr:owningDomain ex:DD_16 ; + pr:hasFormat "STRING(3)" ; + pr:physicalName "CURRENCY_CD" ; + pr:represents ex:BC_16_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance" . +ex:DE_16_01_0002 a pr:DataElement ; + pr:hasIdentifier "DE-16.01-0002" ; pr:hasName "FX Rate to-Euro (Rate)" ; + pr:owningDomain ex:DD_16 ; + pr:hasFormat "DECIMAL(18,8)" ; + pr:hasUnit "Rate" ; + pr:physicalName "FX_RATE_TO_EUR" ; + pr:represents ex:BC_16_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance" . +ex:DE_16_01_0003 a pr:DataElement ; + pr:hasIdentifier "DE-16.01-0003" ; pr:hasName "FX Rate to-USD (Rate)" ; + pr:owningDomain ex:DD_16 ; + pr:hasFormat "DECIMAL(18,8)" ; + pr:hasUnit "Rate" ; + pr:physicalName "FX_RATE_TO_USD" ; + pr:represents ex:BC_16_01_002 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance" . +ex:DE_16_02_0001 a pr:DataElement ; + pr:hasIdentifier "DE-16.02-0001" ; pr:hasName "Marketing Entity Code" ; + pr:owningDomain ex:DD_16 ; + pr:hasFormat "STRING(10)" ; + pr:physicalName "MARKETING_ENTITY_CD" ; + pr:represents ex:BC_16_01_003 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance" . +ex:DE_16_02_0002 a pr:DataElement ; + pr:hasIdentifier "DE-16.02-0002" ; pr:hasName "Fiscal Period Code" ; + pr:owningDomain ex:DD_16 ; + pr:hasFormat "STRING(10)" ; + pr:physicalName "PR_FISCAL_PERIOD_CD" ; + pr:represents ex:BC_16_01_004 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance" . +ex:DE_16_02_0003 a pr:DataElement ; + pr:hasIdentifier "DE-16.02-0003" ; pr:hasName "Fiscal Quarter Code" ; + pr:owningDomain ex:DD_16 ; + pr:hasFormat "STRING(10)" ; + pr:physicalName "PR_FISCAL_QUARTER_CD" ; + pr:represents ex:BC_16_01_004 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance" . +ex:DE_21_01_0001 a pr:DataElement ; + pr:hasIdentifier "DE-21.01-0001" ; pr:hasName "Calendar Date" ; + pr:owningDomain ex:DD_21 ; + pr:hasFormat "DATE" ; + pr:hasUnit "Date" ; + pr:physicalName "DATE_DT" ; + pr:represents ex:BC_21_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Standard Calendar" . +ex:DE_21_01_0002 a pr:DataElement ; + pr:hasIdentifier "DE-21.01-0002" ; pr:hasName "Day of Week Name" ; + pr:owningDomain ex:DD_21 ; + pr:hasFormat "STRING(10)" ; + pr:physicalName "DAY_OF_WEEK_NM" ; + pr:represents ex:BC_21_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Standard Calendar" . +ex:DE_21_01_0003 a pr:DataElement ; + pr:hasIdentifier "DE-21.01-0003" ; pr:hasName "ISO Week Number (Count)" ; + pr:owningDomain ex:DD_21 ; + pr:hasFormat "INTEGER" ; + pr:hasUnit "Count" ; + pr:physicalName "ISO_WEEK_NR" ; + pr:represents ex:BC_21_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Standard Calendar" . +ex:DE_21_01_0004 a pr:DataElement ; + pr:hasIdentifier "DE-21.01-0004" ; pr:hasName "Month Number (Count)" ; + pr:owningDomain ex:DD_21 ; + pr:hasFormat "INTEGER" ; + pr:hasUnit "Count" ; + pr:physicalName "MONTH_NR" ; + pr:represents ex:BC_21_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Standard Calendar" . +ex:DE_21_01_0005 a pr:DataElement ; + pr:hasIdentifier "DE-21.01-0005" ; pr:hasName "Public Holiday Flag" ; + pr:owningDomain ex:DD_21 ; + pr:hasFormat "BOOLEAN" ; + pr:physicalName "PUBLIC_HOLIDAY_FLG" ; + pr:represents ex:BC_21_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Standard Calendar" . +ex:DE_05_01_0001 a pr:DataElement ; + pr:hasIdentifier "DE-05.01-0001" ; pr:hasName "Promotion Type Temporary Price Reduction Flag" ; + pr:owningDomain ex:DD_05 ; + pr:hasFormat "BOOLEAN" ; + pr:physicalName "GL_PROMO_TPR_FLG" ; + pr:represents ex:BC_05_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH Gold (flag)" . +ex:DE_05_01_0002 a pr:DataElement ; + pr:hasIdentifier "DE-05.01-0002" ; pr:hasName "Promotion Type Multibuy Flag" ; + pr:owningDomain ex:DD_05 ; + pr:hasFormat "BOOLEAN" ; + pr:physicalName "GL_PROMO_MULTIBUY_FLG" ; + pr:represents ex:BC_05_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH Gold (flag)" . +ex:DE_05_01_0003 a pr:DataElement ; + pr:hasIdentifier "DE-05.01-0003" ; pr:hasName "Promotion Type Feature Display Flag" ; + pr:owningDomain ex:DD_05 ; + pr:hasFormat "BOOLEAN" ; + pr:physicalName "GL_PROMO_FEATURE_DISPLAY_FLG" ; + pr:represents ex:BC_05_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH Gold (flag)" . +ex:DE_05_01_0004 a pr:DataElement ; + pr:hasIdentifier "DE-05.01-0004" ; pr:hasName "Promotion Type Brochure Flag" ; + pr:owningDomain ex:DD_05 ; + pr:hasFormat "BOOLEAN" ; + pr:physicalName "GL_PROMO_BROCHURE_FLG" ; + pr:represents ex:BC_05_01_001 ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "SODH Gold (flag)" . + +# --- granular measure data elements --------------------------------- +# Same calculation rule as their mother metric, different analysis +# context. They reach meaning through computedBy, never directly. + +ex:DE_06_01_0001 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0001" ; pr:hasName "Sell Out Volume Any-Promotion Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0002 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0002" ; pr:hasName "Sell Out Volume Any-Promotion Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0003 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0003" ; pr:hasName "Sell Out Volume Any-Promotion 4-Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_4W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0004 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0004" ; pr:hasName "Sell Out Volume Any-Promotion 4-Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_4W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0005 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0005" ; pr:hasName "Sell Out Volume Any-Promotion Monthly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_M_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0006 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0006" ; pr:hasName "Sell Out Volume Any-Promotion Monthly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_M_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0007 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0007" ; pr:hasName "Sell Out Volume Any-Promotion MAT (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_MAT_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0008 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0008" ; pr:hasName "Sell Out Volume Any-Promotion MAT (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_ANY_PROMO_MAT_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0009 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0009" ; pr:hasName "Sell Out Volume Non-Promoted Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0010 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0010" ; pr:hasName "Sell Out Volume Non-Promoted Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0011 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0011" ; pr:hasName "Sell Out Volume Non-Promoted 4-Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_4W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0012 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0012" ; pr:hasName "Sell Out Volume Non-Promoted 4-Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_4W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0013 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0013" ; pr:hasName "Sell Out Volume Non-Promoted Monthly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_M_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0014 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0014" ; pr:hasName "Sell Out Volume Non-Promoted Monthly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_M_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0015 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0015" ; pr:hasName "Sell Out Volume Non-Promoted MAT (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_MAT_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0016 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0016" ; pr:hasName "Sell Out Volume Non-Promoted MAT (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_NO_PROMO_MAT_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0017 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0017" ; pr:hasName "Sell Out Volume Promoted Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_PROMO_W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0018 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0018" ; pr:hasName "Sell Out Volume Promoted Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_PROMO_W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0019 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0019" ; pr:hasName "Sell Out Volume Promoted 4-Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_PROMO_4W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0020 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0020" ; pr:hasName "Sell Out Volume Promoted 4-Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_PROMO_4W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0021 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0021" ; pr:hasName "Sell Out Volume Promoted Monthly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_PROMO_M_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0022 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0022" ; pr:hasName "Sell Out Volume Promoted Monthly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_PROMO_M_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0023 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0023" ; pr:hasName "Sell Out Volume Promoted MAT (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_VOLUME_PROMO_MAT_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0024 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0024" ; pr:hasName "Sell Out Volume Promoted MAT (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_VOLUME_PROMO_MAT_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0025 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0025" ; pr:hasName "Sell Out Value Any-Promotion Weekly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_ANY_PROMO_W_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0026 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0026" ; pr:hasName "Sell Out Value Any-Promotion Weekly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_ANY_PROMO_W_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0027 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0027" ; pr:hasName "Sell Out Value Any-Promotion Weekly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_ANY_PROMO_W_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0028 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0028" ; pr:hasName "Sell Out Value Any-Promotion 4-Weekly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_ANY_PROMO_4W_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0029 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0029" ; pr:hasName "Sell Out Value Any-Promotion 4-Weekly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_ANY_PROMO_4W_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0030 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0030" ; pr:hasName "Sell Out Value Any-Promotion 4-Weekly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_ANY_PROMO_4W_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0031 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0031" ; pr:hasName "Sell Out Value Any-Promotion Monthly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_ANY_PROMO_M_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0032 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0032" ; pr:hasName "Sell Out Value Any-Promotion Monthly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_ANY_PROMO_M_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0033 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0033" ; pr:hasName "Sell Out Value Any-Promotion Monthly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_ANY_PROMO_M_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0034 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0034" ; pr:hasName "Sell Out Value Any-Promotion MAT (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_ANY_PROMO_MAT_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0035 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0035" ; pr:hasName "Sell Out Value Any-Promotion MAT (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_ANY_PROMO_MAT_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0036 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0036" ; pr:hasName "Sell Out Value Any-Promotion MAT (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_ANY_PROMO_MAT_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0037 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0037" ; pr:hasName "Sell Out Value Non-Promoted Weekly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_NO_PROMO_W_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0038 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0038" ; pr:hasName "Sell Out Value Non-Promoted Weekly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_NO_PROMO_W_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0039 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0039" ; pr:hasName "Sell Out Value Non-Promoted Weekly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_NO_PROMO_W_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0040 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0040" ; pr:hasName "Sell Out Value Non-Promoted 4-Weekly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_NO_PROMO_4W_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0041 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0041" ; pr:hasName "Sell Out Value Non-Promoted 4-Weekly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_NO_PROMO_4W_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0042 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0042" ; pr:hasName "Sell Out Value Non-Promoted 4-Weekly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_NO_PROMO_4W_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0043 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0043" ; pr:hasName "Sell Out Value Non-Promoted Monthly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_NO_PROMO_M_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0044 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0044" ; pr:hasName "Sell Out Value Non-Promoted Monthly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_NO_PROMO_M_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0045 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0045" ; pr:hasName "Sell Out Value Non-Promoted Monthly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_NO_PROMO_M_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0046 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0046" ; pr:hasName "Sell Out Value Non-Promoted MAT (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_NO_PROMO_MAT_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0047 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0047" ; pr:hasName "Sell Out Value Non-Promoted MAT (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_NO_PROMO_MAT_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0048 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0048" ; pr:hasName "Sell Out Value Non-Promoted MAT (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_NO_PROMO_MAT_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0049 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0049" ; pr:hasName "Sell Out Value Promoted Weekly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_PROMO_W_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0050 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0050" ; pr:hasName "Sell Out Value Promoted Weekly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_PROMO_W_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0051 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0051" ; pr:hasName "Sell Out Value Promoted Weekly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_PROMO_W_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0052 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0052" ; pr:hasName "Sell Out Value Promoted 4-Weekly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_PROMO_4W_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0053 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0053" ; pr:hasName "Sell Out Value Promoted 4-Weekly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_PROMO_4W_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0054 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0054" ; pr:hasName "Sell Out Value Promoted 4-Weekly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_PROMO_4W_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0055 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0055" ; pr:hasName "Sell Out Value Promoted Monthly (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_PROMO_M_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0056 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0056" ; pr:hasName "Sell Out Value Promoted Monthly (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_PROMO_M_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0057 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0057" ; pr:hasName "Sell Out Value Promoted Monthly (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_PROMO_M_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0058 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0058" ; pr:hasName "Sell Out Value Promoted MAT (EUR)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "EUR" ; + pr:physicalName "GL_VALUE_PROMO_MAT_EUR_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0059 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0059" ; pr:hasName "Sell Out Value Promoted MAT (USD)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "USD" ; + pr:physicalName "GL_VALUE_PROMO_MAT_USD_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0060 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0060" ; pr:hasName "Sell Out Value Promoted MAT (LC)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "LC" ; + pr:physicalName "GL_VALUE_PROMO_MAT_LC_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0061 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0061" ; pr:hasName "Sell Out Numeric Distribution Total 4-Weekly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_NUM_DIST_TOT_4W_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0062 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0062" ; pr:hasName "Sell Out Numeric Distribution Total Monthly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_NUM_DIST_TOT_M_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0063 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0063" ; pr:hasName "Sell Out Numeric Distribution Total MAT (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_NUM_DIST_TOT_MAT_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0064 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0064" ; pr:hasName "Sell Out Numeric Distribution Promoted 4-Weekly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_NUM_DIST_PROMO_4W_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0065 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0065" ; pr:hasName "Sell Out Numeric Distribution Promoted Monthly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_NUM_DIST_PROMO_M_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0066 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0066" ; pr:hasName "Sell Out Numeric Distribution Promoted MAT (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_NUM_DIST_PROMO_MAT_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0067 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0067" ; pr:hasName "Sell Out Weighted Distribution Total 4-Weekly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_WGT_DIST_TOT_4W_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0068 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0068" ; pr:hasName "Sell Out Weighted Distribution Total Monthly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_WGT_DIST_TOT_M_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0069 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0069" ; pr:hasName "Sell Out Weighted Distribution Total MAT (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_WGT_DIST_TOT_MAT_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0070 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0070" ; pr:hasName "Sell Out Weighted Distribution Promoted 4-Weekly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_WGT_DIST_PROMO_4W_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0071 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0071" ; pr:hasName "Sell Out Weighted Distribution Promoted Monthly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_WGT_DIST_PROMO_M_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0072 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0072" ; pr:hasName "Sell Out Weighted Distribution Promoted MAT (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_WGT_DIST_PROMO_MAT_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0073 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0073" ; pr:hasName "Sell Out Total Distribution Points 4-Weekly (Index)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "Index" ; + pr:physicalName "GL_TDP_4W_IDX_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0074 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0074" ; pr:hasName "Sell Out Total Distribution Points Monthly (Index)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "Index" ; + pr:physicalName "GL_TDP_M_IDX_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0075 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0075" ; pr:hasName "Sell Out Total Distribution Points MAT (Index)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "Index" ; + pr:physicalName "GL_TDP_MAT_IDX_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0076 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0076" ; pr:hasName "Retailer Stock Forward Volume Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_STOCK_FWD_W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0077 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0077" ; pr:hasName "Retailer Stock Forward Volume Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_STOCK_FWD_W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0078 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0078" ; pr:hasName "Retailer Stock Forward Volume 4-Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_STOCK_FWD_4W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0079 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0079" ; pr:hasName "Retailer Stock Forward Volume 4-Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_STOCK_FWD_4W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0080 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0080" ; pr:hasName "Retailer Stock Forward Volume Monthly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_STOCK_FWD_M_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0081 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0081" ; pr:hasName "Retailer Stock Forward Volume Monthly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_STOCK_FWD_M_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0082 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0082" ; pr:hasName "Retailer Stock Days of Coverage Weekly (Days)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "Days" ; + pr:physicalName "GL_STOCK_COV_W_DAYS_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0083 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0083" ; pr:hasName "Retailer Stock Days of Coverage 4-Weekly (Days)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "Days" ; + pr:physicalName "GL_STOCK_COV_4W_DAYS_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0084 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0084" ; pr:hasName "Retailer Stock Days of Coverage Monthly (Days)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "Days" ; + pr:physicalName "GL_STOCK_COV_M_DAYS_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0085 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0085" ; pr:hasName "Retailer Stock Share Weekly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_STOCK_SHARE_W_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0086 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0086" ; pr:hasName "Retailer Stock Share 4-Weekly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_STOCK_SHARE_4W_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0087 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0087" ; pr:hasName "Retailer Stock Share Monthly (%)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "%" ; + pr:physicalName "GL_STOCK_SHARE_M_PCT_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0088 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0088" ; pr:hasName "Sell Out Baseline Volume Modelled 4-Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_BASELINE_VOL_4W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0089 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0089" ; pr:hasName "Sell Out Baseline Volume Modelled 4-Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_BASELINE_VOL_4W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0090 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0090" ; pr:hasName "Sell Out Baseline Volume Modelled Monthly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_BASELINE_VOL_M_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0091 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0091" ; pr:hasName "Sell Out Baseline Volume Modelled Monthly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_BASELINE_VOL_M_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0092 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0092" ; pr:hasName "Sell Out Incremental Volume Modelled 4-Weekly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_INCR_VOL_4W_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0093 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0093" ; pr:hasName "Sell Out Incremental Volume Modelled 4-Weekly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_INCR_VOL_4W_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0094 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0094" ; pr:hasName "Sell Out Incremental Volume Modelled Monthly (9L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "9L" ; + pr:physicalName "GL_INCR_VOL_M_9L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . +ex:DE_06_01_0095 a pr:DataElement ; + pr:hasIdentifier "DE-06.01-0095" ; pr:hasName "Sell Out Incremental Volume Modelled Monthly (L)" ; + pr:owningDomain ex:DD_06 ; + pr:hasFormat "DECIMAL(18,4)" ; + pr:hasUnit "L" ; + pr:physicalName "GL_INCR_VOL_M_L_NM" ; + pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Snowflake (SODH Gold)" . + +# --- BR-013 wiring: each mother metric and the variants that implement it + +ex:M_06_01_001 pr:computedBy ex:DE_06_01_0001 , ex:DE_06_01_0002 , ex:DE_06_01_0003 , ex:DE_06_01_0004 , + ex:DE_06_01_0005 , ex:DE_06_01_0006 , ex:DE_06_01_0007 , ex:DE_06_01_0008 , + ex:DE_06_01_0009 , ex:DE_06_01_0010 , ex:DE_06_01_0011 , ex:DE_06_01_0012 , + ex:DE_06_01_0013 , ex:DE_06_01_0014 , ex:DE_06_01_0015 , ex:DE_06_01_0016 , + ex:DE_06_01_0017 , ex:DE_06_01_0018 , ex:DE_06_01_0019 , ex:DE_06_01_0020 , + ex:DE_06_01_0021 , ex:DE_06_01_0022 , ex:DE_06_01_0023 , ex:DE_06_01_0024 . +ex:M_06_01_002 pr:computedBy ex:DE_06_01_0025 , ex:DE_06_01_0026 , ex:DE_06_01_0027 , ex:DE_06_01_0028 , + ex:DE_06_01_0029 , ex:DE_06_01_0030 , ex:DE_06_01_0031 , ex:DE_06_01_0032 , + ex:DE_06_01_0033 , ex:DE_06_01_0034 , ex:DE_06_01_0035 , ex:DE_06_01_0036 , + ex:DE_06_01_0037 , ex:DE_06_01_0038 , ex:DE_06_01_0039 , ex:DE_06_01_0040 , + ex:DE_06_01_0041 , ex:DE_06_01_0042 , ex:DE_06_01_0043 , ex:DE_06_01_0044 , + ex:DE_06_01_0045 , ex:DE_06_01_0046 , ex:DE_06_01_0047 , ex:DE_06_01_0048 , + ex:DE_06_01_0049 , ex:DE_06_01_0050 , ex:DE_06_01_0051 , ex:DE_06_01_0052 , + ex:DE_06_01_0053 , ex:DE_06_01_0054 , ex:DE_06_01_0055 , ex:DE_06_01_0056 , + ex:DE_06_01_0057 , ex:DE_06_01_0058 , ex:DE_06_01_0059 , ex:DE_06_01_0060 . +ex:M_06_01_003 pr:computedBy ex:DE_06_01_0061 , ex:DE_06_01_0062 , ex:DE_06_01_0063 , ex:DE_06_01_0064 , + ex:DE_06_01_0065 , ex:DE_06_01_0066 . +ex:M_06_01_004 pr:computedBy ex:DE_06_01_0067 , ex:DE_06_01_0068 , ex:DE_06_01_0069 , ex:DE_06_01_0070 , + ex:DE_06_01_0071 , ex:DE_06_01_0072 . +ex:M_06_01_005 pr:computedBy ex:DE_06_01_0073 , ex:DE_06_01_0074 , ex:DE_06_01_0075 . +ex:M_06_01_006 pr:computedBy ex:DE_06_01_0076 , ex:DE_06_01_0077 , ex:DE_06_01_0078 , ex:DE_06_01_0079 , + ex:DE_06_01_0080 , ex:DE_06_01_0081 . +ex:M_06_01_007 pr:computedBy ex:DE_06_01_0082 , ex:DE_06_01_0083 , ex:DE_06_01_0084 . +ex:M_06_01_008 pr:computedBy ex:DE_06_01_0085 , ex:DE_06_01_0086 , ex:DE_06_01_0087 . +ex:M_06_01_009 pr:computedBy ex:DE_06_01_0088 , ex:DE_06_01_0089 , ex:DE_06_01_0090 , ex:DE_06_01_0091 . +ex:M_06_01_010 pr:computedBy ex:DE_06_01_0092 , ex:DE_06_01_0093 , ex:DE_06_01_0094 , ex:DE_06_01_0095 . diff --git a/scripts/apply_arbitration_sodh.py b/scripts/apply_arbitration_sodh.py index e0f7cbc..ea2fe35 100644 --- a/scripts/apply_arbitration_sodh.py +++ b/scripts/apply_arbitration_sodh.py @@ -204,27 +204,38 @@ def main(): " renamed=%s" % newname if newname else "")) # ---- 3. insert the missing concepts -------------------------------------- + # idempotent: identical duplicated blocks merge in RDF, so SHACL would + # never flag them -- the file grows while the graph stays valid. + todo_c = [c for c in NEW_CONCEPTS + if not re.search(r'^%s a ' % re.escape(c[0]), text, re.M)] anchor = re.search(r'\n(?=ex:BO_\w+ a pr:BusinessObject ;)', text) - if anchor: - blocks = "\n".join(concept_block(*c) for c in NEW_CONCEPTS) + if anchor and todo_c: + blocks = "\n".join(concept_block(*c) for c in todo_c) text = (text[:anchor.start()] + "\n\n" + "# --- concepts added in v1.1 migration -------------------------------\n" + "# Six of these belong to other domains: DRAFT definitions proposed by the\n" + "# DGO, flagged TO_ARBITRATE. OW-007 blocks publication until ratified.\n" + blocks + "\n" + text[anchor.start():]) report.append("inserted %d Business Concepts (%d TO_ARBITRATE)" - % (len(NEW_CONCEPTS), sum(1 for c in NEW_CONCEPTS if c[6]))) + % (len(todo_c), sum(1 for c in todo_c if c[6]))) + elif not todo_c: + report.append("all %d Business Concepts already present, skipped" + % len(NEW_CONCEPTS)) # ---- 4. append the objects produced by the splits ------------------------ + todo_o = [o for o in NEW_OBJECTS + if not re.search(r'^%s a ' % re.escape(o[0]), text, re.M)] tail = re.search(r'\n(?=ex:M_\w+ a pr:Metric ;|ex:DO_\w+ a pr:DataObject ;)', text) - if tail: - blocks = "\n".join(object_block(*o) for o in NEW_OBJECTS) + if tail and todo_o: + blocks = "\n".join(object_block(*o) for o in todo_o) text = (text[:tail.start()] + "\n\n" + "# --- Business Objects from the v1.1 splits ---------------------------\n" + "# 'Customer & Outlet' and 'Currency & Exchange Rates' had no single\n" + "# subject. Split proposed to DD-04 and DD-16, hence TO_ARBITRATE.\n" + blocks + "\n" + text[tail.start():]) - report.append("inserted %d Business Objects from splits" % len(NEW_OBJECTS)) + report.append("inserted %d Business Objects from splits" % len(todo_o)) + elif not todo_o: + report.append("Business Objects from splits already present, skipped") # ---- report -------------------------------------------------------------- print() diff --git a/scripts/apply_br013_sodh.py b/scripts/apply_br013_sodh.py new file mode 100644 index 0000000..7540426 --- /dev/null +++ b/scripts/apply_br013_sodh.py @@ -0,0 +1,479 @@ +#!/usr/bin/env python3 +""" +SODH - BR-013 alignment, last step of the v1.1 migration +========================================================= +Regenerates the Metric and Data Element sections of instances/sodh.ttl from the +v0.7 back-doc, which has been ahead of the TTL since the divergence found at +audit time. This is the migration that puts the flow back the right way round: +after it, the TTL is the source and the workbook becomes a generated artefact. + +USAGE + python3 scripts/apply_br013_sodh.py # dry run + python3 scripts/apply_br013_sodh.py --apply # rewrite, .bak kept + +WHAT IT FIXES + 37 BLOCKING DataElementMeaningShape -- no element had a route to meaning + 15 BLOCKING physicalName on a Metric -- layer leak + 15 WARNING hasGranularity on a Metric + 6 WARNING monitoredBy on a Data Object + +WHAT IT DOES + 1. 15 metrics -> 10 mother metrics carrying the harmonized calculation + rule, each with a formula, a unit and a measured Concept. No physical + name, no granularity: both belong elsewhere now. + 2. 95 measure Data Elements generated, each computedBy its mother metric, + each carrying the physical name the metric used to hold. + 3. 37 dimensional Data Elements given a represents towards their Concept. + With 2, this closes the XOR: every element reaches meaning by exactly + one route. + 4. Three concepts created because the XOR forces them to be named -- + Country, Marketing Entity, Fiscal Period had elements but no notion. + TO_ARBITRATE like the others. + 5. Steward removed from the 6 Data Objects: it is inherited now. + 6. hasGrainElement on the 4 DIMENSION Data Objects only. + +WHY FACT TABLES GET NO GRAIN ELEMENTS + A fact table's grain is carried by its foreign keys, and OW-006 says a + foreign key is not a Data Element -- so a fact object has no element of its + own to point at. Its grain is already expressed, by references towards the + dimension objects it joins. Forcing hasGrainElement onto facts would mean + either breaking OW-006 or pointing at another object's elements, which + GrainConsistencyShape rejects. Nothing is lost: the information is there. +""" +import os +import re +import shutil +import sys + +REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +TTL = os.path.join(REPO, "instances", "sodh.ttl") +BACKDOC = os.path.join(REPO, "instances", "SODH_data.xlsx") +W = 78 + +# ---- mother metric -> the Concept it measures ------------------------------ +METRIC_CONCEPT = { + "M-06.01-001": "ex:BC_06_01_001", # Sell Out Volume -> Sell Out + "M-06.01-002": "ex:BC_06_01_001", # Sell Out Value -> Sell Out + "M-06.01-003": "ex:BC_06_01_004", # Numeric Distribution -> Retail Distribution + "M-06.01-004": "ex:BC_06_01_004", # Weighted Distribution -> Retail Distribution + "M-06.01-005": "ex:BC_06_01_004", # Total Distribution Pts -> Retail Distribution + "M-06.01-006": "ex:BC_06_01_002", # Forward Stock Volume -> Retailer Stock + "M-06.01-007": "ex:BC_06_01_002", # Days of Coverage -> Retailer Stock + "M-06.01-008": "ex:BC_06_01_002", # Stock Share -> Retailer Stock + "M-06.01-009": "ex:BC_06_01_005", # Baseline Volume -> Sell Out Baseline + "M-06.01-010": "ex:BC_06_01_005", # Incremental Volume -> Sell Out Baseline +} + +# ---- dimensional element -> the Concept it represents ---------------------- +# Exact ids first, then id prefixes. Every dimensional element must land +# somewhere: that is what the XOR is for. +DE_CONCEPT_EXACT = { + "DE-04.01-0006": "ex:BC_04_01_002", # Outlet Type -> Outlet + "DE-04.01-0007": "ex:BC_04_01_002", # Channel -> Outlet + "DE-04.01-0010": "ex:BC_04_01_002", # Point of Sale Count -> Outlet + "DE-04.01-0008": "ex:BC_04_01_003", # Country Code -> Country + "DE-04.01-0009": "ex:BC_04_01_003", # Country Name -> Country + "DE-16.01-0001": "ex:BC_16_01_001", # Currency Code -> Currency + "DE-16.01-0002": "ex:BC_16_01_002", # FX Rate to-Euro -> Exchange Rate + "DE-16.01-0003": "ex:BC_16_01_002", # FX Rate to-USD -> Exchange Rate + "DE-16.02-0001": "ex:BC_16_01_003", # Marketing Entity -> Marketing Entity + "DE-16.02-0002": "ex:BC_16_01_004", # Fiscal Period Code -> Fiscal Period + "DE-16.02-0003": "ex:BC_16_01_004", # Fiscal Quarter Code -> Fiscal Period +} +DE_CONCEPT_PREFIX = [ + ("DE-10.01", "ex:BC_10_01_001"), # product hierarchy -> Product + ("DE-04.01", "ex:BC_04_01_001"), # trade hierarchy -> Customer + ("DE-21.01", "ex:BC_21_01_001"), # calendar -> Calendar Date + ("DE-05.01", "ex:BC_05_01_001"), # promotion flags -> Promotion +] + +# ---- concepts the XOR forces us to name ------------------------------------ +NEW_CONCEPTS = [ + ("ex:BC_04_01_003", "BC-04.01-003", "Country", "ex:DD_04", "ex:ST_DD_04", + "A sovereign territory used as the geographic frame for retail measurement, " + "identified by its ISO 3166 code. Distinct from Customer and Outlet: it is where " + "they operate, not what they are."), + ("ex:BC_16_01_003", "BC-16.01-003", "Marketing Entity", "ex:DD_16", "ex:ST_DD_16", + "An organisational unit of the group holding commercial responsibility for a market, " + "and the level at which financial results are consolidated."), + ("ex:BC_16_01_004", "BC-16.01-004", "Fiscal Period", "ex:DD_16", "ex:ST_DD_16", + "A reporting interval of the Pernod Ricard fiscal year, which runs July to June. " + "Distinct from Calendar Date: the fiscal frame does not align with the Gregorian one."), +] + +# ---- grain of the DIMENSION objects (fact grain lives in references) ------- +GRAIN = { + "ex:DO_10_01_001": ["ex:DE_10_01_0005"], # Product Dimension -> SKU Code + "ex:DO_04_01_001": ["ex:DE_04_01_0005"], # Customer Dimension -> Customer Tier-2 Code + "ex:DO_16_01_001": ["ex:DE_16_01_0001"], # Currency Dimension -> Currency Code + "ex:DO_21_01_001": ["ex:DE_21_01_0001"], # Calendar Dimension -> Calendar Date +} + +UNIT_FIX = {"9L / L": "9L", "Currency EUR/USD/LC": "EUR", "%": "%", + "Index": "Index", "Days": "Days"} + + +def iri(ident): + """BO-06.01-001 -> ex:BO_06_01_001""" + return "ex:" + ident.replace("-", "_", 1).replace(".", "_").replace("-", "_") + + +def esc(text): + return text.replace("\\", "\\\\").replace('"', '\\"') + + +def _xlsx_rows(path): + """ + Minimal .xlsx reader: zipfile + ElementTree, no third-party dependency. + + openpyxl would do this in three lines, but the validation venv is already + pinned tightly (pyshacl 0.26.0 for Python 3.9) and adding a dependency to a + migration script that runs once is a poor trade. Handles what a back-doc + needs: shared strings, inline strings, numbers, and sheet names. + """ + import zipfile + import xml.etree.ElementTree as ET + + NS = "{http://schemas.openxmlformats.org/spreadsheetml/2006/main}" + REL = "{http://schemas.openxmlformats.org/officeDocument/2006/relationships}" + PKG = "{http://schemas.openxmlformats.org/package/2006/relationships}" + + with zipfile.ZipFile(path) as z: + shared = [] + if "xl/sharedStrings.xml" in z.namelist(): + for si in ET.fromstring(z.read("xl/sharedStrings.xml")): + shared.append("".join(t.text or "" for t in si.iter(NS + "t"))) + + rels = {} + for rel in ET.fromstring(z.read("xl/_rels/workbook.xml.rels")): + rels[rel.get("Id")] = rel.get("Target").lstrip("/") + + sheets = [] + for sh in ET.fromstring(z.read("xl/workbook.xml")).iter(NS + "sheet"): + target = rels.get(sh.get(REL + "id"), "") + if not target.startswith("xl/"): + target = "xl/" + target + sheets.append((sh.get("name"), target)) + + for name, target in sheets: + if target not in z.namelist(): + continue + rows = [] + for row in ET.fromstring(z.read(target)).iter(NS + "row"): + cells = [] + for c in row.iter(NS + "c"): + v = c.find(NS + "v") + if c.get("t") == "s" and v is not None: + cells.append(shared[int(v.text)]) + elif c.get("t") == "inlineStr": + cells.append("".join(t.text or "" for t in c.iter(NS + "t"))) + else: + cells.append(v.text if v is not None else "") + rows.append([(x or "").strip() for x in cells]) + yield name, rows + + +def _text_rows(path): + """Tab-separated fallback, for back-docs exported as plain text.""" + sheet, rows = None, [] + for raw in open(path, encoding="utf-8", errors="replace"): + if raw.startswith("## Sheet:"): + if sheet: + yield sheet, rows + sheet, rows = raw.split(":", 1)[1].strip(), [] + elif sheet is not None: + rows.append([c.strip() for c in raw.rstrip("\n").split("\t")]) + if sheet: + yield sheet, rows + + +def parse_backdoc(path): + """ + Read the back-doc, whichever form it takes. + + A real .xlsx is a ZIP (magic PK\x03\x04); some pipelines hand over a + tab-separated text export of the same content. Sniff rather than assume: + guessing from the extension is what made this script fail the first time. + """ + with open(path, "rb") as fh: + is_zip = fh.read(4) == b"PK\x03\x04" + reader = _xlsx_rows if is_zip else _text_rows + + out = {"metrics": [], "elements": []} + for name, rows in reader(path): + key = None + if name.strip().startswith("6"): + key = "metrics" + elif name.strip().startswith("7"): + key = "elements" + if not key: + continue + for cells in rows: + if len(cells) < 5 or not cells[0]: + continue + if key == "metrics" and cells[0].startswith("M-"): + out[key].append(cells) + elif key == "elements" and cells[0].startswith("DE-"): + out[key].append(cells) + if not out["metrics"] or not out["elements"]: + raise SystemExit( + "Back-doc read but empty: %d metrics, %d elements.\n" + "Expected sheets starting with '6.' (Mother Metrics) and '7.' " + "(Data Elements) in %s" % (len(out["metrics"]), len(out["elements"]), path)) + return out + + +def concept_for(de_id): + if de_id in DE_CONCEPT_EXACT: + return DE_CONCEPT_EXACT[de_id] + for prefix, bc in DE_CONCEPT_PREFIX: + if de_id.startswith(prefix): + return bc + return None + + +def build_metrics(metrics): + out = ["# --- mother metrics, BR-013 -----------------------------------------", + "# One harmonized calculation rule each. The granular variants are Data", + "# Elements linked by computedBy. No physical name (layer leak) and no", + "# granularity (a calculation rule has no rows).", ""] + for r in metrics: + mid, name, bo, formula, unit = r[0], r[1], r[2], r[3], r[4] + unit = UNIT_FIX.get(unit.split(" (")[0], unit.split(" (")[0]) + out.append("%s a pr:Metric ;" % iri(mid)) + out.append(' pr:hasIdentifier "%s" ; pr:hasName "%s" ;' % (mid, esc(name))) + out.append(" pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ;") + out.append(' pr:hasFormula "%s" ;' % esc(formula)) + out.append(' pr:hasUnit "%s" ;' % esc(unit)) + out.append(" pr:measures %s ;" % METRIC_CONCEPT[mid]) + out.append(' pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; ' + 'pr:hasSource "SODH back-doc v0.7" .') + return "\n".join(out) + + +def build_elements(elements): + measure, dimensional = [], [] + for r in elements: + (deid, name, domain, computed, fmt, unit, source, phys, do) = r[:9] + dom = "ex:DD_" + deid.split("-")[1].split(".")[0] + block = ["%s a pr:DataElement ;" % iri(deid), + ' pr:hasIdentifier "%s" ; pr:hasName "%s" ;' % (deid, esc(name)), + " pr:owningDomain %s ;" % dom, + ' pr:hasFormat "%s" ;' % esc(fmt)] + if unit and unit != "-": + block.append(' pr:hasUnit "%s" ;' % esc(unit)) + if phys and phys != "-": + block.append(' pr:physicalName "%s" ;' % esc(phys)) + if computed == "(dimensional)": + bc = concept_for(deid) + if not bc: + raise SystemExit("No concept mapped for %s -- the XOR would fail." % deid) + block.append(" pr:represents %s ;" % bc) + block.append(' pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; ' + 'pr:hasSource "%s" .' % esc(source)) + dimensional.append("\n".join(block)) + else: + block.append(' pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; ' + 'pr:hasSource "%s" .' % esc(source)) + measure.append("\n".join(block)) + return measure, dimensional + + +def build_computed_by(elements): + """Metric -> its granular elements. Asserted from the metric side.""" + by_metric = {} + name_to_id = {r[1]: r[0] for r in parse_backdoc(BACKDOC)["metrics"]} + for r in elements: + if r[3] == "(dimensional)": + continue + mid = name_to_id.get(r[3]) + if mid: + by_metric.setdefault(mid, []).append(iri(r[0])) + out = ["# --- BR-013 wiring: each mother metric and the variants that implement it", + ""] + for mid, des in by_metric.items(): + chunks = [des[i:i + 4] for i in range(0, len(des), 4)] + lines = [" , ".join(c) for c in chunks] + out.append("%s pr:computedBy %s ." % (iri(mid), " ,\n ".join(lines))) + return "\n".join(out), sum(len(v) for v in by_metric.values()) + + +def rebuild_has_element(text, elements): + """ + Re-attach every Data Element to its Data Object, from the back-doc column. + + Without this the 95 generated measure elements would be orphans: no path to + the physical layer, and no steward, since stewardship is inherited through + the object. Not caught by any shape -- which is why it is worth doing here + rather than waiting for the validator to complain. + """ + by_do = {} + for r in elements: + do = r[8].strip() + if do and do != "-": + by_do.setdefault(iri(do), []).append(iri(r[0])) + n = 0 + for do, des in by_do.items(): + pat = re.compile(r'(^%s a pr:DataObject ;.*?)\n\s*pr:hasElement[^;]*;' % re.escape(do), + re.S | re.M) + chunks = [des[i:i + 4] for i in range(0, len(des), 4)] + clause = "\n pr:hasElement " + " ,\n ".join(" , ".join(c) for c in chunks) + " ;" + if pat.search(text): + text = pat.sub(lambda m: m.group(1) + clause, text, count=1) + n += 1 + return text, n, {k: len(v) for k, v in by_do.items()} + + +def rebuild_has_metric(text, metrics): + """ + Re-point hasMetric on the Business Objects at the mother metrics. + + Removing the old metric definitions is not enough: the Business Objects + still name them, and because hasMetric has rdfs:range pr:Metric, RDFS + entailment types those dangling IRIs as metrics. They then become focus + nodes carrying no identifier, no name, no formula -- ten ghosts, six + violations each. Deleting a subject means deleting what points at it. + """ + by_bo = {} + for r in metrics: + by_bo.setdefault(iri(r[2]), []).append(iri(r[0])) + + text = re.sub(r'\n\s*pr:hasMetric[^;]*;', '', text) + n = 0 + for bo, ms in by_bo.items(): + pat = re.compile(r'(^%s a pr:BusinessObject ;.*?)(\n\s*pr:hasStatus)' % re.escape(bo), + re.S | re.M) + if pat.search(text): + text = pat.sub(r'\1\n pr:hasMetric %s ;\2' % " , ".join(ms), text, count=1) + n += 1 + return text, n, by_bo + + +def concept_block(c): + i, ident, name, dom, st, definition = c + return ("%s a pr:BusinessConcept ;\n" + ' pr:hasIdentifier "%s" ; pr:hasName "%s" ;\n' + " pr:owningDomain %s ; pr:ownedBy %s ;\n" + ' pr:hasBusinessDefinition "%s" ;\n' + ' pr:arbitrationStatus "TO_ARBITRATE" ;\n' + ' pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; ' + 'pr:hasSource "DGO proposal, pending ratification by the owning domain" .' + % (i, ident, esc(name), dom, st, esc(definition))) + + +def main(): + apply_changes = "--apply" in sys.argv + for f in (TTL, BACKDOC): + if not os.path.exists(f): + print("Not found: %s" % f) + sys.exit(2) + + doc = parse_backdoc(BACKDOC) + text = original = open(TTL, encoding="utf-8").read() + report = [] + + # 1. drop the old metric and data element blocks + n_old_m = len(re.findall(r'^ex:M_\w+ a pr:Metric ;', text, re.M)) + n_old_de = len(re.findall(r'^ex:DE_\w+ a pr:DataElement ;', text, re.M)) + text = re.sub(r'^ex:M_\w+ a pr:Metric ;.*?\.\s*\n(?=^ex:|\Z)', '', text, flags=re.S | re.M) + text = re.sub(r'^ex:DE_\w+ a pr:DataElement ;.*?\.\s*\n(?=^ex:|\Z)', '', text, flags=re.S | re.M) + report.append("removed %d old metrics and %d old data elements" % (n_old_m, n_old_de)) + + # 2. steward is inherited, not declared on a Data Object + n_st = 0 + for m in re.finditer(r'^ex:DO_\w+ a pr:DataObject ;.*?\.\s*\n', text, re.S | re.M): + block = m.group(0) + new = re.sub(r'\s*pr:monitoredBy\s+ex:\w+\s*;', ' ;', block) + new = re.sub(r';\s*;', ' ;', new) + if new != block: + n_st += 1 + text = text.replace(block, new, 1) + report.append("removed monitoredBy from %d Data Objects (inherited now)" % n_st) + + # 3. grain, dimension objects only + n_g = 0 + for do, grain in GRAIN.items(): + pat = re.compile(r'(^%s a pr:DataObject ;.*?)(\n\s*pr:hasStatus)' % re.escape(do), + re.S | re.M) + if pat.search(text): + text = pat.sub(r'\1\n pr:hasGrainElement %s ;\2' % " , ".join(grain), text, count=1) + n_g += 1 + report.append("grain declared on %d dimension Data Objects " + "(fact grain stays in references)" % n_g) + + # 4. the three concepts the XOR forces us to name + # idempotent: a concept already in the file is left alone. Duplicated + # blocks would be INVISIBLE to SHACL -- identical triples merge under RDF + # set semantics, so the graph validates while the file carries redundant + # text. A script that can be re-run must check before it inserts. + todo = [c for c in NEW_CONCEPTS + if not re.search(r'^%s a ' % re.escape(c[0]), text, re.M)] + if len(todo) < len(NEW_CONCEPTS): + report.append("skipped %d concept(s) already present" + % (len(NEW_CONCEPTS) - len(todo))) + anchor = re.search(r'\n(?=ex:BO_\w+ a pr:BusinessObject ;)', text) + blocks = "\n".join(concept_block(c) for c in todo) + if todo: + text = (text[:anchor.start()] + "\n\n" + + "# --- concepts required by the meaning XOR ---------------------------\n" + + "# Country, Marketing Entity and Fiscal Period had Data Elements but no\n" + + "# notion behind them. The rule forced them to be named.\n" + + blocks + "\n" + text[anchor.start():]) + report.append("added %d concepts required by the XOR (TO_ARBITRATE)" % len(todo)) + + # 5. metrics, elements, wiring + measure, dimensional = build_elements(doc["elements"]) + wiring, n_wired = build_computed_by(doc["elements"]) + text = text.rstrip() + "\n\n\n" + build_metrics(doc["metrics"]) + "\n\n" + text += ("# --- dimensional data elements --------------------------------------\n" + "# Each represents the Concept it carries: the first of the two routes\n" + "# to business meaning.\n\n" + "\n".join(dimensional) + "\n\n") + text += ("# --- granular measure data elements ---------------------------------\n" + "# Same calculation rule as their mother metric, different analysis\n" + "# context. They reach meaning through computedBy, never directly.\n\n" + + "\n".join(measure) + "\n\n" + wiring + "\n") + report.append("wrote %d mother metrics, %d dimensional and %d measure elements" + % (len(doc["metrics"]), len(dimensional), len(measure))) + report.append("wired %d computedBy links" % n_wired) + + text, n_bo, per_bo = rebuild_has_metric(text, doc["metrics"]) + report.append("re-pointed hasMetric on %d Business Objects (%s)" + % (n_bo, ", ".join("%s=%d" % (k.replace("ex:BO_", "BO-"), len(v)) + for k, v in sorted(per_bo.items())))) + + text, n_do, counts = rebuild_has_element(text, doc["elements"]) + report.append("re-attached elements to %d Data Objects (%s)" + % (n_do, ", ".join("%s=%d" % (k.replace("ex:DO_", "DO-"), v) + for k, v in sorted(counts.items())))) + + print() + print("SODH BR-013 ALIGNMENT %s" % ("APPLY" if apply_changes else "DRY RUN")) + print("=" * W) + for line in report: + print(" " + line) + print("=" * W) + defined = set(re.findall(r'^(ex:M_\w+) a pr:Metric ;', text, re.M)) + referenced = set(re.findall(r'ex:M_\w+', text)) + dangling = referenced - defined + print(" dangling metric references: %s" + % (", ".join(sorted(dangling)) if dangling else "none")) + print(" Metrics %d | Data Elements %d | Concepts %d | computedBy %d | " + "physicalName on Metric %d" + % (len(re.findall(r'a pr:Metric', text)), + len(re.findall(r'a pr:DataElement', text)), + len(re.findall(r'a pr:BusinessConcept', text)), + n_wired, + len(re.findall(r'a pr:Metric ;[^.]*?physicalName', text, re.S)))) + print("=" * W) + + if text != original and apply_changes: + shutil.copy2(TTL, TTL + ".bak") + open(TTL, "w", encoding="utf-8").write(text) + print(" written, backup at %s.bak" % os.path.basename(TTL)) + elif text != original: + print(" dry run -- re-run with --apply to write") + print() + + +if __name__ == "__main__": + main() diff --git a/scripts/run_shacl_validation.py b/scripts/run_shacl_validation.py index 1a20b45..7da322a 100644 --- a/scripts/run_shacl_validation.py +++ b/scripts/run_shacl_validation.py @@ -236,13 +236,41 @@ def main(): meta_shacl=False, ) + def shape_label(g, res, SH): + """ + A readable name for the shape that fired. + + sh:sourceShape on a property constraint is a blank node, which prints as + 'ne775aabb...' and tells the reader nothing. Fall back, in order, to the + constrained path, then to the named NodeShape that owns the blank node, + then to the constraint component. + """ + shape = g.value(res, SH.sourceShape) + if shape is not None and not str(shape).startswith("n"): + name = str(shape).rsplit("/", 1)[-1] + if name and not name.startswith("N"): + return name + path = g.value(res, SH.resultPath) + if path is not None: + owner = None + for s_, p_, o_ in g.triples((None, SH.property, shape)): + owner = s_ + break + base = str(path).rsplit("/", 1)[-1].rsplit("#", 1)[-1] + if owner is not None and not str(owner).startswith("n"): + return "%s / %s" % (str(owner).rsplit("/", 1)[-1], base) + return "path %s" % base + comp = g.value(res, SH.sourceConstraintComponent) + if comp is not None: + return str(comp).rsplit("#", 1)[-1] + return "(unnamed shape)" + rows = [] for res in results.subjects(RDF.type, SH.ValidationResult): sev = str(results.value(res, SH.resultSeverity)).rsplit("#", 1)[-1] focus = str(results.value(res, SH.focusNode)).rsplit("/", 1)[-1] msg = str(results.value(res, SH.resultMessage) or "") - src = str(results.value(res, SH.sourceShape) or "").rsplit("/", 1)[-1] - rows.append((sev, src, focus, msg)) + rows.append((sev, shape_label(results, res, SH), focus, msg)) violations = sum(1 for r in rows if r[0] == "Violation") warnings = len(rows) - violations