Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7793def268 |
+114
-60
@@ -67,31 +67,60 @@ ex:SD_10_01 a pr:SubDomain ;
|
||||
pr:belongsTo ex:DD_10 ;
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0" .
|
||||
ex:SD_04_01 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-04.01" ; pr:hasName "Customer & Outlet" ;
|
||||
pr:hasName "Customer Structure" ;
|
||||
pr:hasIdentifier "SD-04.01" ;
|
||||
pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ;
|
||||
pr:belongsTo ex:DD_04 ;
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0" .
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0"
|
||||
.
|
||||
ex:SD_16_01 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-16.01" ; pr:hasName "Currency & Exchange Rates" ;
|
||||
pr:hasName "Currency & Exchange Rate" ;
|
||||
pr:hasIdentifier "SD-16.01" ;
|
||||
pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ;
|
||||
pr:belongsTo ex:DD_16 ;
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0" .
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0"
|
||||
.
|
||||
ex:SD_16_02 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-16.02" ; pr:hasName "Marketing Entity & Fiscal Calendar" ;
|
||||
pr:hasName "Fiscal Calendar" ;
|
||||
pr:hasIdentifier "SD-16.02" ;
|
||||
pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ;
|
||||
pr:belongsTo ex:DD_16 ;
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0" .
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0"
|
||||
.
|
||||
ex:SD_21_01 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-21.01" ; pr:hasName "Calendar" ;
|
||||
pr:hasName "Standard Calendar" ;
|
||||
pr:hasIdentifier "SD-21.01" ;
|
||||
pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ;
|
||||
pr:belongsTo ex:DD_21 ;
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0" .
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0"
|
||||
.
|
||||
ex:SD_05_01 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-05.01" ; pr:hasName "Promotion" ;
|
||||
pr:owningDomain ex:DD_05 ; pr:ownedBy ex:ST_DD_05 ;
|
||||
pr:belongsTo ex:DD_05 ;
|
||||
pr:hasStatus "PUBLISHED" ; pr:hasVersion "1.0" .
|
||||
|
||||
|
||||
# --- sub-domains from the v1.1 structure proposal --------------------
|
||||
# 'Customer & Outlet' and 'Marketing Entity & Fiscal Calendar' had the
|
||||
# same defect as the compound Business Objects: a name joined by '&'
|
||||
# has no single subject. Same rule, one level up.
|
||||
ex:SD_04_02 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-04.02" ; pr:hasName "Outlet & Points of Sale" ;
|
||||
pr:belongsTo ex:DD_04 ; pr:owningDomain ex:DD_04 ;
|
||||
pr:arbitrationStatus "TO_ARBITRATE" ;
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, split of a compound sub-domain" .
|
||||
ex:SD_04_03 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-04.03" ; pr:hasName "Geography" ;
|
||||
pr:belongsTo ex:DD_04 ; pr:owningDomain ex:DD_04 ;
|
||||
pr:arbitrationStatus "TO_ARBITRATE" ;
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, split of a compound sub-domain" .
|
||||
ex:SD_16_03 a pr:SubDomain ;
|
||||
pr:hasIdentifier "SD-16.03" ; pr:hasName "Organisation Structure" ;
|
||||
pr:belongsTo ex:DD_16 ; pr:owningDomain ex:DD_16 ;
|
||||
pr:arbitrationStatus "TO_ARBITRATE" ;
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, split of a compound sub-domain" .
|
||||
|
||||
ex:BC_06_01_001 a pr:BusinessConcept ;
|
||||
pr:hasIdentifier "BC-06.01-001" ; pr:hasName "Sell Out" ;
|
||||
pr:owningDomain ex:DD_06 ; pr:ownedBy ex:ST_DD_06 ;
|
||||
@@ -168,20 +197,22 @@ ex:BC_21_01_001 a pr:BusinessConcept ;
|
||||
# --- 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" ;
|
||||
ex:BC_04_03_001 a pr:BusinessConcept ;
|
||||
pr:hasIdentifier "BC-04.03-001" ; 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" ;
|
||||
ex:BC_16_03_001 a pr:BusinessConcept ;
|
||||
pr:hasBusinessRule "Named Marketing Entity, not Management Entity: the element is Marketing Entity Code and the column is MARKETING_ENTITY_CD. To be confirmed by DD-16." ;
|
||||
pr:hasIdentifier "BC-16.03-001" ; 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:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain"
|
||||
.
|
||||
ex:BC_16_02_001 a pr:BusinessConcept ;
|
||||
pr:hasIdentifier "BC-16.02-001" ; 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" ;
|
||||
@@ -193,8 +224,6 @@ ex:BO_06_01_001 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 ;
|
||||
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 ;
|
||||
@@ -203,8 +232,6 @@ 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: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 ;
|
||||
@@ -213,8 +240,6 @@ 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: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 ;
|
||||
@@ -223,8 +248,6 @@ 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: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 ;
|
||||
@@ -233,64 +256,95 @@ 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: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]" .
|
||||
pr:belongsTo ex:SD_10_01 ;
|
||||
pr:hasName "Product Hierarchy" ;
|
||||
pr:hasIdentifier "BO-10.01-001" ;
|
||||
pr:owningDomain ex:DD_10 ; pr:ownedBy ex:ST_DD_10 ; pr:monitoredBy ex:ST_DD_10 ;
|
||||
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]" .
|
||||
pr:belongsTo ex:SD_04_01 ;
|
||||
pr:hasName "Customer Hierarchy" ;
|
||||
pr:hasIdentifier "BO-04.01-001" ;
|
||||
pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; pr:monitoredBy ex:ST_DD_04 ;
|
||||
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:aboutConcept ex:BC_16_01_001 ;
|
||||
pr:belongsTo ex:SD_16_01 ;
|
||||
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]" .
|
||||
pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; pr:monitoredBy ex:ST_DD_16 ;
|
||||
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]" .
|
||||
pr:belongsTo ex:SD_21_01 ;
|
||||
pr:hasName "Analysis Period" ;
|
||||
pr:hasIdentifier "BO-21.01-001" ;
|
||||
pr:owningDomain ex:DD_21 ; pr:ownedBy ex:ST_DD_21 ; pr:monitoredBy ex:ST_DD_21 ;
|
||||
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]" .
|
||||
|
||||
|
||||
# --- Business Objects from the v1.1 splits ---------------------------
|
||||
# 'Customer & Outlet' and 'Currency & Exchange Rates' had no single
|
||||
# subject. Split proposed to DD-04 and DD-16, hence TO_ARBITRATE.
|
||||
ex:BO_04_01_002 a pr:BusinessObject ;
|
||||
pr:hasIdentifier "BO-04.01-002" ; pr:hasName "Outlet" ;
|
||||
pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ;
|
||||
pr:belongsTo ex:SD_04_01 ; pr:monitoredBy ex:ST_DD_04 ;
|
||||
ex:BO_04_02_001 a pr:BusinessObject ;
|
||||
pr:aboutConcept ex:BC_04_01_002 ;
|
||||
pr:belongsTo ex:SD_04_02 ;
|
||||
pr:hasIdentifier "BO-04.02-001" ; pr:hasName "Outlet" ;
|
||||
pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; pr:monitoredBy ex:ST_DD_04 ;
|
||||
pr:arbitrationStatus "TO_ARBITRATE" ;
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer -> SODH [split from BO-04.01-001, proposed to DD-04]" .
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "MDM Customer -> SODH [split from BO-04.01-001, proposed to DD-04]"
|
||||
.
|
||||
ex:BO_16_01_002 a pr:BusinessObject ;
|
||||
pr:hasIdentifier "BO-16.01-002" ; pr:hasName "Exchange Rate" ;
|
||||
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_002 ;
|
||||
pr:belongsTo ex:SD_16_01 ;
|
||||
pr:hasIdentifier "BO-16.01-002" ; pr:hasName "Exchange Rate" ;
|
||||
pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; pr:monitoredBy ex:ST_DD_16 ;
|
||||
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]" .
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "Group Finance -> SODH [split from BO-16.01-001, proposed to DD-16]"
|
||||
.
|
||||
|
||||
|
||||
# --- business objects for the borrowed concepts -----------------------
|
||||
# Country, Fiscal Period and Marketing Entity had a concept but nothing
|
||||
# to hold it. Proposed to DD-04 and DD-16, hence TO_ARBITRATE.
|
||||
ex:BO_04_03_001 a pr:BusinessObject ;
|
||||
pr:aboutConcept ex:BC_04_03_001 ;
|
||||
pr:belongsTo ex:SD_04_03 ;
|
||||
pr:hasIdentifier "BO-04.03-001" ; pr:hasName "Country" ;
|
||||
pr:owningDomain ex:DD_04 ; pr:ownedBy ex:ST_DD_04 ; pr:monitoredBy ex:ST_DD_04 ;
|
||||
pr:arbitrationStatus "TO_ARBITRATE" ;
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain"
|
||||
.
|
||||
ex:BO_16_02_001 a pr:BusinessObject ;
|
||||
pr:aboutConcept ex:BC_16_02_001 ;
|
||||
pr:belongsTo ex:SD_16_02 ;
|
||||
pr:hasIdentifier "BO-16.02-001" ; pr:hasName "Fiscal Period" ;
|
||||
pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; pr:monitoredBy ex:ST_DD_16 ;
|
||||
pr:arbitrationStatus "TO_ARBITRATE" ;
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain"
|
||||
.
|
||||
ex:BO_16_03_001 a pr:BusinessObject ;
|
||||
pr:aboutConcept ex:BC_16_03_001 ;
|
||||
pr:belongsTo ex:SD_16_03 ;
|
||||
pr:hasIdentifier "BO-16.03-001" ; pr:hasName "Marketing Entity" ;
|
||||
pr:owningDomain ex:DD_16 ; pr:ownedBy ex:ST_DD_16 ; pr:monitoredBy ex:ST_DD_16 ;
|
||||
pr:arbitrationStatus "TO_ARBITRATE" ;
|
||||
pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; pr:hasSource "DGO proposal, pending ratification by the owning domain"
|
||||
.
|
||||
|
||||
ex:DO_06_01_001 a pr:DataObject ;
|
||||
pr:hasIdentifier "DO-06.01-001" ; pr:hasName "Sell Out Volume Dataset" ;
|
||||
@@ -585,14 +639,14 @@ ex:DE_04_01_0008 a pr:DataElement ;
|
||||
pr:owningDomain ex:DD_04 ;
|
||||
pr:hasFormat "STRING(2)" ;
|
||||
pr:physicalName "COUNTRY_CD" ;
|
||||
pr:represents ex:BC_04_01_003 ;
|
||||
pr:represents ex:BC_04_03_001 ;
|
||||
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:represents ex:BC_04_03_001 ;
|
||||
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)" ;
|
||||
@@ -630,21 +684,21 @@ ex:DE_16_02_0001 a pr:DataElement ;
|
||||
pr:owningDomain ex:DD_16 ;
|
||||
pr:hasFormat "STRING(10)" ;
|
||||
pr:physicalName "MARKETING_ENTITY_CD" ;
|
||||
pr:represents ex:BC_16_01_003 ;
|
||||
pr:represents ex:BC_16_03_001 ;
|
||||
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:represents ex:BC_16_02_001 ;
|
||||
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:represents ex:BC_16_02_001 ;
|
||||
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" ;
|
||||
|
||||
@@ -95,7 +95,7 @@ NEW_CONCEPTS = [
|
||||
|
||||
# ------------------------------------------------------------------- new object
|
||||
NEW_OBJECTS = [
|
||||
("ex:BO_04_01_002", "BO-04.01-002", "Outlet", "ex:DD_04", "ex:ST_DD_04", "ex:SD_04_01",
|
||||
("ex:BO_04_02_001", "BO-04.02-001", "Outlet", "ex:DD_04", "ex:ST_DD_04", "ex:SD_04_02",
|
||||
"ex:BC_04_01_002", [], "MDM Customer -> SODH [split from BO-04.01-001, proposed to DD-04]"),
|
||||
("ex:BO_16_01_002", "BO-16.01-002", "Exchange Rate", "ex:DD_16", "ex:ST_DD_16", "ex:SD_16_01",
|
||||
"ex:BC_16_01_002", [], "Group Finance -> SODH [split from BO-16.01-001, proposed to DD-16]"),
|
||||
@@ -176,7 +176,13 @@ def main():
|
||||
continue
|
||||
block = m.group(1)
|
||||
|
||||
# strip what a previous run may have written, so re-running is a no-op.
|
||||
# Duplicated clauses carrying the SAME value merge under RDF set
|
||||
# semantics: the graph stays valid and SHACL sees nothing, while the
|
||||
# file quietly grows a redundant line on every pass.
|
||||
new_block = re.sub(r'[ \t]*pr:composedOf\s+[^";]*;[ \t]*\n', '', block)
|
||||
new_block = re.sub(r'[ \t]*pr:(aboutConcept|usesConcept)\s+[^";]*;[ \t]*\n',
|
||||
'', new_block)
|
||||
clause = ' pr:aboutConcept %s ;\n' % about
|
||||
if uses:
|
||||
clause += ' pr:usesConcept %s ;\n' % " , ".join(uses)
|
||||
@@ -244,6 +250,13 @@ def main():
|
||||
for line in report:
|
||||
print(" " + line)
|
||||
print("=" * W)
|
||||
doubled = []
|
||||
for m in re.finditer(r'^(ex:\w+) a pr:\w+ ;(.*?)\.\s*\n', text, re.S | re.M):
|
||||
for prop in ("pr:hasName", "pr:aboutConcept", "pr:belongsTo"):
|
||||
if len(re.findall(r'(?<![\w:])%s\s' % re.escape(prop), m.group(2))) > 1:
|
||||
doubled.append("%s/%s" % (m.group(1), prop))
|
||||
print(" duplicated single-valued properties: %s"
|
||||
% (", ".join(doubled) if doubled else "none"))
|
||||
bo = len(re.findall(r'a pr:BusinessObject', text))
|
||||
bc = len(re.findall(r'a pr:BusinessConcept', text))
|
||||
print(" Business Objects %d | Business Concepts %d | composedOf left %d"
|
||||
|
||||
@@ -71,14 +71,14 @@ 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-04.01-0008": "ex:BC_04_03_001", # Country Code -> Country
|
||||
"DE-04.01-0009": "ex:BC_04_03_001", # 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-16.02-0001": "ex:BC_16_03_001", # Marketing Entity -> Marketing Entity
|
||||
"DE-16.02-0002": "ex:BC_16_02_001", # Fiscal Period Code -> Fiscal Period
|
||||
"DE-16.02-0003": "ex:BC_16_02_001", # Fiscal Quarter Code -> Fiscal Period
|
||||
}
|
||||
DE_CONCEPT_PREFIX = [
|
||||
("DE-10.01", "ex:BC_10_01_001"), # product hierarchy -> Product
|
||||
@@ -89,14 +89,17 @@ DE_CONCEPT_PREFIX = [
|
||||
|
||||
# ---- 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",
|
||||
# Final identifiers from the outset. Creating them under one id and
|
||||
# renumbering them later broke idempotence: the second run no longer found
|
||||
# the original id and recreated the concept alongside the renamed one.
|
||||
("ex:BC_04_03_001", "BC-04.03-001", "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",
|
||||
("ex:BC_16_03_001", "BC-16.03-001", "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",
|
||||
("ex:BC_16_02_001", "BC-16.02-001", "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."),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SODH - structure proposed for the borrowed domains
|
||||
===================================================
|
||||
Gives the nine TO_ARBITRATE concepts a home: a Business Object and a
|
||||
Sub-Domain each, per the structure arbitrated with Bastien on 2026-07-27.
|
||||
|
||||
USAGE
|
||||
python3 scripts/apply_structure_sodh.py # dry run
|
||||
python3 scripts/apply_structure_sodh.py --apply # rewrite, .bak kept
|
||||
|
||||
STILL A PROPOSAL
|
||||
Everything created here stays TO_ARBITRATE. DD-04, DD-10, DD-16 and DD-21
|
||||
own these perimeters; the DGO is proposing a coherent structure, not
|
||||
ratifying one. Replacing padding with an equally unilateral structure
|
||||
would trade one problem for a tidier version of the same problem. The flag
|
||||
comes off when Helene Puchot, Anas El Kesri and Gaelle Seret say so, and
|
||||
OW-007 blocks publication until then.
|
||||
|
||||
IDENTIFIERS ARE FINAL FROM CREATION
|
||||
Identifiers encode the sub-domain (BO-04.02-001 lives in SD-04.02), so the
|
||||
upstream scripts now mint them correctly rather than having this one
|
||||
renumber afterwards. Renaming after creation broke idempotence: the script
|
||||
that created an object stopped recognising its own output and made a second
|
||||
copy on the next run.
|
||||
|
||||
COMPOUND SUB-DOMAINS SPLIT TOO
|
||||
'Customer & Outlet' and 'Marketing Entity & Fiscal Calendar' have the same
|
||||
defect as the Business Objects that were split earlier: a name joined by
|
||||
'&' has no single subject. Same rule, one level up.
|
||||
"""
|
||||
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")
|
||||
W = 78
|
||||
|
||||
# No IRI renaming here. Objects are created with their final identifiers by
|
||||
# the upstream scripts: renumbering after the fact broke idempotence, because
|
||||
# the creating script then no longer recognised its own output.
|
||||
# ---- sub-domains ----------------------------------------------------------
|
||||
SD_RENAME = {
|
||||
"ex:SD_04_01": "Customer Structure",
|
||||
"ex:SD_16_01": "Currency & Exchange Rate",
|
||||
"ex:SD_16_02": "Fiscal Calendar",
|
||||
"ex:SD_21_01": "Standard Calendar",
|
||||
}
|
||||
SD_NEW = [
|
||||
("ex:SD_04_02", "SD-04.02", "Outlet & Points of Sale", "ex:DD_04"),
|
||||
("ex:SD_04_03", "SD-04.03", "Geography", "ex:DD_04"),
|
||||
("ex:SD_16_03", "SD-16.03", "Organisation Structure", "ex:DD_16"),
|
||||
]
|
||||
|
||||
# ---- business objects -----------------------------------------------------
|
||||
BO_RENAME = {
|
||||
"ex:BO_10_01_001": "Product Hierarchy",
|
||||
"ex:BO_04_01_001": "Customer Hierarchy",
|
||||
"ex:BO_21_01_001": "Analysis Period",
|
||||
}
|
||||
BO_NEW = [
|
||||
("ex:BO_04_03_001", "BO-04.03-001", "Country", "ex:DD_04", "ex:ST_DD_04",
|
||||
"ex:SD_04_03", "ex:BC_04_03_001"),
|
||||
("ex:BO_16_02_001", "BO-16.02-001", "Fiscal Period", "ex:DD_16", "ex:ST_DD_16",
|
||||
"ex:SD_16_02", "ex:BC_16_02_001"),
|
||||
("ex:BO_16_03_001", "BO-16.03-001", "Marketing Entity", "ex:DD_16", "ex:ST_DD_16",
|
||||
"ex:SD_16_03", "ex:BC_16_03_001"),
|
||||
]
|
||||
|
||||
# ---- where each object finally sits ---------------------------------------
|
||||
BELONGS = {
|
||||
"ex:BO_10_01_001": "ex:SD_10_01",
|
||||
"ex:BO_04_01_001": "ex:SD_04_01",
|
||||
"ex:BO_04_02_001": "ex:SD_04_02",
|
||||
"ex:BO_04_03_001": "ex:SD_04_03",
|
||||
"ex:BO_16_01_001": "ex:SD_16_01",
|
||||
"ex:BO_16_01_002": "ex:SD_16_01",
|
||||
"ex:BO_16_02_001": "ex:SD_16_02",
|
||||
"ex:BO_16_03_001": "ex:SD_16_03",
|
||||
"ex:BO_21_01_001": "ex:SD_21_01",
|
||||
}
|
||||
|
||||
# ---- subject of each borrowed object --------------------------------------
|
||||
ABOUT = {
|
||||
"ex:BO_10_01_001": "ex:BC_10_01_001", # Product Hierarchy -> Product
|
||||
"ex:BO_04_01_001": "ex:BC_04_01_001", # Customer Hierarchy -> Customer
|
||||
"ex:BO_04_02_001": "ex:BC_04_01_002", # Outlet -> Outlet
|
||||
"ex:BO_04_03_001": "ex:BC_04_03_001", # Country -> Country
|
||||
"ex:BO_16_01_001": "ex:BC_16_01_001", # Currency -> Currency
|
||||
"ex:BO_16_01_002": "ex:BC_16_01_002", # Exchange Rate -> Exchange Rate
|
||||
"ex:BO_16_02_001": "ex:BC_16_02_001", # Fiscal Period -> Fiscal Period
|
||||
"ex:BO_16_03_001": "ex:BC_16_03_001", # Marketing Entity -> Marketing Entity
|
||||
"ex:BO_21_01_001": "ex:BC_21_01_001", # Analysis Period -> Calendar Date
|
||||
}
|
||||
|
||||
MARKETING_NOTE = ("Named Marketing Entity, not Management Entity: the element is "
|
||||
"Marketing Entity Code and the column is MARKETING_ENTITY_CD. "
|
||||
"To be confirmed by DD-16.")
|
||||
|
||||
|
||||
def sd_block(i, ident, name, domain):
|
||||
return ('%s a pr:SubDomain ;\n'
|
||||
' pr:hasIdentifier "%s" ; pr:hasName "%s" ;\n'
|
||||
' pr:belongsTo %s ; pr:owningDomain %s ;\n'
|
||||
' pr:arbitrationStatus "TO_ARBITRATE" ;\n'
|
||||
' pr:hasStatus "DRAFT" ; pr:hasVersion "1.1" ; '
|
||||
'pr:hasSource "DGO proposal, split of a compound sub-domain" .'
|
||||
% (i, ident, name, domain, domain))
|
||||
|
||||
|
||||
def bo_block(i, ident, name, domain, steward, sd, bc):
|
||||
return ('%s a pr:BusinessObject ;\n'
|
||||
' pr:hasIdentifier "%s" ; pr:hasName "%s" ;\n'
|
||||
' pr:owningDomain %s ; pr:ownedBy %s ;\n'
|
||||
' pr:belongsTo %s ; pr:monitoredBy %s ;\n'
|
||||
' pr:aboutConcept %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, name, domain, steward, sd, steward, bc))
|
||||
|
||||
|
||||
def _split_clauses(body):
|
||||
"""Split a Turtle predicate list on ';' that sit outside string literals."""
|
||||
out, buf, i, n = [], [], 0, len(body)
|
||||
while i < n:
|
||||
c = body[i]
|
||||
if c == '"':
|
||||
j = i + 1
|
||||
while j < n and body[j] != '"':
|
||||
j += 2 if body[j] == "\\" else 1
|
||||
j = min(j + 1, n)
|
||||
buf.append(body[i:j]); i = j; continue
|
||||
if c == ";":
|
||||
out.append("".join(buf)); buf = []; i += 1; continue
|
||||
buf.append(c); i += 1
|
||||
out.append("".join(buf))
|
||||
return out
|
||||
|
||||
|
||||
def set_prop(text, subject, prop, value):
|
||||
"""
|
||||
Set or replace a single-valued property inside a subject block.
|
||||
|
||||
Clause-level, not regex-level: a property can sit mid-line
|
||||
(pr:hasIdentifier "X" ; pr:hasName "Y" ;) and its value can contain a
|
||||
semicolon inside the literal. A line-anchored pattern silently misses both
|
||||
and APPENDS instead of replacing, which produces a second value and a
|
||||
cardinality violation -- exactly what happened on the first run here.
|
||||
"""
|
||||
pat = re.compile(r'(^%s a pr:\w+ ;)(.*?)(\.\s*\n)' % re.escape(subject), re.S | re.M)
|
||||
m = pat.search(text)
|
||||
if not m:
|
||||
return text, False
|
||||
kept = [c for c in _split_clauses(m.group(2))
|
||||
if c.strip() and not re.match(r'\s*%s\s' % re.escape(prop), c)]
|
||||
kept.insert(0, "\n %s %s " % (prop, value))
|
||||
body = " ;".join(kept)
|
||||
if not body.endswith("\n"):
|
||||
body = body.rstrip() + "\n "
|
||||
return text[:m.start()] + m.group(1) + body + m.group(3) + text[m.end():], True
|
||||
|
||||
|
||||
def main():
|
||||
apply_changes = "--apply" in sys.argv
|
||||
if not os.path.exists(TTL):
|
||||
print("Not found: %s" % TTL)
|
||||
sys.exit(2)
|
||||
text = original = open(TTL, encoding="utf-8").read()
|
||||
report = []
|
||||
|
||||
# 2. sub-domains
|
||||
for sd, name in SD_RENAME.items():
|
||||
text, ok = set_prop(text, sd, "pr:hasName", '"%s"' % name)
|
||||
if ok:
|
||||
report.append("renamed %s -> %s" % (sd.replace("ex:SD_", "SD-"), name))
|
||||
|
||||
todo_sd = [s for s in SD_NEW if not re.search(r'^%s a ' % re.escape(s[0]), text, re.M)]
|
||||
if todo_sd:
|
||||
anchor = re.search(r'\n(?=ex:BC_\w+ a pr:BusinessConcept ;|ex:BO_\w+ a pr:BusinessObject ;)',
|
||||
text)
|
||||
blocks = "\n".join(sd_block(*s) for s in todo_sd)
|
||||
text = (text[:anchor.start()] + "\n\n"
|
||||
+ "# --- sub-domains from the v1.1 structure proposal --------------------\n"
|
||||
+ "# 'Customer & Outlet' and 'Marketing Entity & Fiscal Calendar' had the\n"
|
||||
+ "# same defect as the compound Business Objects: a name joined by '&'\n"
|
||||
+ "# has no single subject. Same rule, one level up.\n"
|
||||
+ blocks + "\n" + text[anchor.start():])
|
||||
report.append("created %d sub-domains%s"
|
||||
% (len(todo_sd), "" if todo_sd else " (already present)"))
|
||||
|
||||
# 3. new business objects
|
||||
todo_bo = [b for b in BO_NEW if not re.search(r'^%s a ' % re.escape(b[0]), text, re.M)]
|
||||
if todo_bo:
|
||||
anchor = re.search(r'\n(?=ex:DO_\w+ a pr:DataObject ;|ex:M_\w+ a pr:Metric ;)', text)
|
||||
blocks = "\n".join(bo_block(*b) for b in todo_bo)
|
||||
text = (text[:anchor.start()] + "\n\n"
|
||||
+ "# --- business objects for the borrowed concepts -----------------------\n"
|
||||
+ "# Country, Fiscal Period and Marketing Entity had a concept but nothing\n"
|
||||
+ "# to hold it. Proposed to DD-04 and DD-16, hence TO_ARBITRATE.\n"
|
||||
+ blocks + "\n" + text[anchor.start():])
|
||||
report.append("created %d business objects%s"
|
||||
% (len(todo_bo), "" if todo_bo else " (already present)"))
|
||||
|
||||
# 4. renames, placement, subject
|
||||
for bo, name in BO_RENAME.items():
|
||||
text, _ = set_prop(text, bo, "pr:hasName", '"%s"' % name)
|
||||
report.append("renamed %d business objects to the agreed nomenclature" % len(BO_RENAME))
|
||||
|
||||
n_b = n_a = 0
|
||||
for bo, sd in BELONGS.items():
|
||||
text, ok = set_prop(text, bo, "pr:belongsTo", sd)
|
||||
n_b += ok
|
||||
for bo, bc in ABOUT.items():
|
||||
text, ok = set_prop(text, bo, "pr:aboutConcept", bc)
|
||||
n_a += ok
|
||||
report.append("placed %d objects in their sub-domain, %d subjects confirmed" % (n_b, n_a))
|
||||
|
||||
# 5. the naming caveat, recorded on the object rather than in a side note
|
||||
text, ok = set_prop(text, "ex:BC_16_03_001", "pr:hasBusinessRule", '"%s"' % MARKETING_NOTE)
|
||||
if ok:
|
||||
report.append("recorded the Marketing/Management naming caveat on the concept")
|
||||
|
||||
# ---- report
|
||||
print()
|
||||
print("SODH STRUCTURE PROPOSAL %s" % ("APPLY" if apply_changes else "DRY RUN"))
|
||||
print("=" * W)
|
||||
for line in report:
|
||||
print(" " + line)
|
||||
print("=" * W)
|
||||
defined = set(re.findall(r'^(ex:\w+) a ', text, re.M))
|
||||
dangling = sorted(set(re.findall(r'\bex:\w+', text)) - defined)
|
||||
print(" dangling references: %s" % (", ".join(dangling) if dangling else "none"))
|
||||
for cls in ("SubDomain", "BusinessObject", "BusinessConcept"):
|
||||
ids = re.findall(r'^(ex:\w+) a pr:%s\b' % cls, text, re.M)
|
||||
dup = [i for i in set(ids) if ids.count(i) > 1]
|
||||
print(" %-16s %3d duplicates %d" % (cls, len(ids), len(dup)))
|
||||
doubled = []
|
||||
for m in re.finditer(r'^(ex:\w+) a pr:\w+ ;(.*?)\.\s*\n', text, re.S | re.M):
|
||||
for prop in ("pr:hasName", "pr:hasIdentifier", "pr:belongsTo", "pr:aboutConcept"):
|
||||
if len(re.findall(r'%s\s' % re.escape(prop), m.group(2))) > 1:
|
||||
doubled.append("%s/%s" % (m.group(1), prop))
|
||||
print(" duplicated single-valued properties: %s"
|
||||
% (", ".join(doubled) if doubled else "none"))
|
||||
arb = len(re.findall(r'pr:arbitrationStatus "TO_ARBITRATE"', text))
|
||||
print(" TO_ARBITRATE %3d (nothing publishes until the domains ratify)" % arb)
|
||||
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()
|
||||
Reference in New Issue
Block a user